Make Enumerator available as builtin
[jruby.git] / src / org / jruby / Ruby.java
blob261fcfc34b34deea0e066cff05b099e7cd383d5f
1 /*
2 **** BEGIN LICENSE BLOCK *****
3 * Version: CPL 1.0/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Common Public
6 * License Version 1.0 (the "License"); you may not use this file
7 * except in compliance with the License. You may obtain a copy of
8 * the License at http://www.eclipse.org/legal/cpl-v10.html
10 * Software distributed under the License is distributed on an "AS
11 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
12 * implied. See the License for the specific language governing
13 * rights and limitations under the License.
15 * Copyright (C) 2001 Chad Fowler <chadfowler@chadfowler.com>
16 * Copyright (C) 2001 Alan Moore <alan_moore@gmx.net>
17 * Copyright (C) 2001-2002 Benoit Cerrina <b.cerrina@wanadoo.fr>
18 * Copyright (C) 2001-2004 Jan Arne Petersen <jpetersen@uni-bonn.de>
19 * Copyright (C) 2002-2004 Anders Bengtsson <ndrsbngtssn@yahoo.se>
20 * Copyright (C) 2004 Thomas E Enebo <enebo@acm.org>
21 * Copyright (C) 2004-2005 Charles O Nutter <headius@headius.com>
22 * Copyright (C) 2004 Stefan Matthias Aust <sma@3plus4.de>
23 * Copyright (C) 2006 Miguel Covarrubias <mlcovarrubias@gmail.com>
24 * Copyright (C) 2006 Michael Studman <codehaus@michaelstudman.com>
25 * Copyright (C) 2006 Ola Bini <ola@ologix.com>
26 * Copyright (C) 2007 Nick Sieger <nicksieger@gmail.com>
28 * Alternatively, the contents of this file may be used under the terms of
29 * either of the GNU General Public License Version 2 or later (the "GPL"),
30 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
31 * in which case the provisions of the GPL or the LGPL are applicable instead
32 * of those above. If you wish to allow use of your version of this file only
33 * under the terms of either the GPL or the LGPL, and not to allow others to
34 * use your version of this file under the terms of the CPL, indicate your
35 * decision by deleting the provisions above and replace them with the notice
36 * and other provisions required by the GPL or the LGPL. If you do not delete
37 * the provisions above, a recipient may use your version of this file under
38 * the terms of any one of the CPL, the GPL or the LGPL.
39 ***** END LICENSE BLOCK *****/
40 package org.jruby;
42 import java.io.ByteArrayInputStream;
43 import java.io.File;
44 import java.io.FileDescriptor;
45 import java.io.IOException;
46 import java.io.InputStream;
47 import java.io.PrintStream;
48 import java.io.UnsupportedEncodingException;
49 import java.lang.ref.WeakReference;
50 import java.lang.reflect.Field;
51 import java.util.ArrayList;
52 import java.util.Collections;
53 import java.util.Hashtable;
54 import java.util.HashMap;
55 import java.util.IdentityHashMap;
56 import java.util.Iterator;
57 import java.util.List;
58 import java.util.Map;
59 import java.util.Random;
60 import java.util.Set;
61 import java.util.Stack;
62 import java.util.Vector;
63 import java.util.WeakHashMap;
64 import java.util.concurrent.ArrayBlockingQueue;
65 import java.util.concurrent.ConcurrentHashMap;
66 import java.util.concurrent.ExecutorService;
67 import java.util.concurrent.Executors;
68 import java.util.concurrent.SynchronousQueue;
69 import java.util.concurrent.ThreadFactory;
70 import java.util.concurrent.ThreadPoolExecutor;
71 import java.util.concurrent.TimeUnit;
72 import java.util.concurrent.atomic.AtomicInteger;
74 import org.jruby.anno.TypePopulator;
75 import org.jruby.ast.Node;
76 import org.jruby.ast.executable.RubiniusRunner;
77 import org.jruby.ast.executable.Script;
78 import org.jruby.ast.executable.YARVCompiledRunner;
79 import org.jruby.common.RubyWarnings;
80 import org.jruby.common.IRubyWarnings.ID;
81 import org.jruby.compiler.ASTCompiler;
82 import org.jruby.compiler.ASTInspector;
83 import org.jruby.compiler.NotCompilableException;
84 import org.jruby.compiler.impl.StandardASMCompiler;
85 import org.jruby.compiler.yarv.StandardYARVCompiler;
86 import org.jruby.evaluator.ASTInterpreter;
87 import org.jruby.exceptions.JumpException;
88 import org.jruby.exceptions.RaiseException;
89 import org.jruby.ext.JRubyPOSIXHandler;
90 import org.jruby.ext.LateLoadingLibrary;
91 import org.jruby.ext.posix.POSIX;
92 import org.jruby.ext.posix.POSIXFactory;
93 import org.jruby.internal.runtime.GlobalVariables;
94 import org.jruby.internal.runtime.ThreadService;
95 import org.jruby.internal.runtime.ValueAccessor;
96 import org.jruby.javasupport.JavaSupport;
97 import org.jruby.parser.Parser;
98 import org.jruby.parser.ParserConfiguration;
99 import org.jruby.runtime.Binding;
100 import org.jruby.runtime.Block;
101 import org.jruby.runtime.CacheMap;
102 import org.jruby.runtime.CallbackFactory;
103 import org.jruby.runtime.DynamicScope;
104 import org.jruby.runtime.EventHook;
105 import org.jruby.runtime.Frame;
106 import org.jruby.runtime.GlobalVariable;
107 import org.jruby.runtime.IAccessor;
108 import org.jruby.runtime.ObjectAllocator;
109 import org.jruby.runtime.ObjectSpace;
110 import org.jruby.runtime.ThreadContext;
111 import org.jruby.runtime.builtin.IRubyObject;
112 import org.jruby.runtime.load.Library;
113 import org.jruby.runtime.load.LoadService;
114 import org.jruby.util.BuiltinScript;
115 import org.jruby.util.ByteList;
116 import org.jruby.util.IOInputStream;
117 import org.jruby.util.IOOutputStream;
118 import org.jruby.util.JRubyClassLoader;
119 import org.jruby.util.JavaNameMangler;
120 import org.jruby.util.KCode;
121 import org.jruby.util.SafePropertyAccessor;
122 import org.jruby.util.collections.WeakHashSet;
123 import org.jruby.util.io.ChannelDescriptor;
126 * The Ruby object represents the top-level of a JRuby "instance" in a given VM.
127 * JRuby supports spawning multiple instances in the same JVM. Generally, objects
128 * created under these instances are tied to a given runtime, for such details
129 * as identity and type, because multiple Ruby instances means there are
130 * multiple instances of each class. This means that in multi-runtime mode
131 * (or really, multi-VM mode, where each JRuby instance is a ruby "VM"), objects
132 * generally can't be transported across runtimes without marshaling.
134 * This class roots everything that makes the JRuby runtime function, and
135 * provides a number of utility methods for constructing global types and
136 * accessing global runtime structures.
138 public final class Ruby {
140 * Returns a new instance of the JRuby runtime configured with defaults.
142 * @return the JRuby runtime
143 * @see org.jruby.RubyInstanceConfig
145 public static Ruby newInstance() {
146 return newInstance(new RubyInstanceConfig());
150 * Returns a new instance of the JRuby runtime configured as specified.
152 * @param config The instance configuration
153 * @return The JRuby runtime
154 * @see org.jruby.RubyInstanceConfig
156 public static Ruby newInstance(RubyInstanceConfig config) {
157 Ruby ruby = new Ruby(config);
158 ruby.init();
159 if (RUNTIME_THREADLOCAL) {
160 setCurrentInstance(ruby);
162 return ruby;
166 * Returns a new instance of the JRuby runtime configured with the given
167 * input, output and error streams and otherwise default configuration
168 * (except where specified system properties alter defaults).
170 * @param in the custom input stream
171 * @param out the custom output stream
172 * @param err the custom error stream
173 * @return the JRuby runtime
174 * @see org.jruby.RubyInstanceConfig
176 public static Ruby newInstance(InputStream in, PrintStream out, PrintStream err) {
177 RubyInstanceConfig config = new RubyInstanceConfig();
178 config.setInput(in);
179 config.setOutput(out);
180 config.setError(err);
181 return newInstance(config);
185 * Create and initialize a new JRuby runtime. The properties of the
186 * specified RubyInstanceConfig will be used to determine various JRuby
187 * runtime characteristics.
189 * @param config The configuration to use for the new instance
190 * @see org.jruby.RubyInstanceConfig
192 private Ruby(RubyInstanceConfig config) {
193 this.config = config;
194 this.threadService = new ThreadService(this);
195 if(config.isSamplingEnabled()) {
196 org.jruby.util.SimpleSampler.registerThreadContext(threadService.getCurrentContext());
199 this.in = config.getInput();
200 this.out = config.getOutput();
201 this.err = config.getError();
202 this.objectSpaceEnabled = config.isObjectSpaceEnabled();
203 this.profile = config.getProfile();
204 this.currentDirectory = config.getCurrentDirectory();
205 this.kcode = config.getKCode();
209 * Evaluates a script under the current scope (perhaps the top-level
210 * scope) and returns the result (generally the last value calculated).
211 * This version goes straight into the interpreter, bypassing compilation
212 * and runtime preparation typical to normal script runs.
214 * @param script The scriptlet to run
215 * @returns The result of the eval
217 public IRubyObject evalScriptlet(String script) {
218 ThreadContext context = getCurrentContext();
219 Node node = parseEval(script, "<script>", context.getCurrentScope(), 0);
221 try {
222 return ASTInterpreter.eval(this, context, node, context.getFrameSelf(), Block.NULL_BLOCK);
223 } catch (JumpException.ReturnJump rj) {
224 throw newLocalJumpError("return", (IRubyObject)rj.getValue(), "unexpected return");
225 } catch (JumpException.BreakJump bj) {
226 throw newLocalJumpError("break", (IRubyObject)bj.getValue(), "unexpected break");
227 } catch (JumpException.RedoJump rj) {
228 throw newLocalJumpError("redo", (IRubyObject)rj.getValue(), "unexpected redo");
233 * Parse and execute the specified script
234 * This differs from the other methods in that it accepts a string-based script and
235 * parses and runs it as though it were loaded at a command-line. This is the preferred
236 * way to start up a new script when calling directly into the Ruby object (which is
237 * generally *dis*couraged.
239 * @param script The contents of the script to run as a normal, root script
240 * @return The last value of the script
242 public IRubyObject executeScript(String script, String filename) {
243 byte[] bytes;
245 try {
246 bytes = script.getBytes(KCode.NONE.getKCode());
247 } catch (UnsupportedEncodingException e) {
248 bytes = script.getBytes();
251 Node node = parseInline(new ByteArrayInputStream(bytes), filename, null);
252 Frame frame = getCurrentContext().getCurrentFrame();
254 frame.setFile(node.getPosition().getFile());
255 frame.setLine(node.getPosition().getStartLine());
256 return runNormally(node, false);
260 * Run the script contained in the specified input stream, using the
261 * specified filename as the name of the script being executed. The stream
262 * will be read fully before being parsed and executed. The given filename
263 * will be used for the ruby $PROGRAM_NAME and $0 global variables in this
264 * runtime.
266 * This method is intended to be called once per runtime, generally from
267 * Main or from main-like top-level entry points.
269 * As part of executing the script loaded from the input stream, various
270 * RubyInstanceConfig properties will be used to determine whether to
271 * compile the script before execution or run with various wrappers (for
272 * looping, printing, and so on, see jruby -help).
274 * @param inputStream The InputStream from which to read the script contents
275 * @param filename The filename to use when parsing, and for $PROGRAM_NAME
276 * and $0 ruby global variables.
278 public void runFromMain(InputStream inputStream, String filename) {
279 IAccessor d = new ValueAccessor(newString(filename));
280 getGlobalVariables().define("$PROGRAM_NAME", d);
281 getGlobalVariables().define("$0", d);
283 for (Iterator i = config.getOptionGlobals().entrySet().iterator(); i.hasNext();) {
284 Map.Entry entry = (Map.Entry) i.next();
285 Object value = entry.getValue();
286 IRubyObject varvalue;
287 if (value != null) {
288 varvalue = newString(value.toString());
289 } else {
290 varvalue = getTrue();
292 getGlobalVariables().set("$" + entry.getKey().toString(), varvalue);
296 if(config.isYARVEnabled()) {
297 new YARVCompiledRunner(this, inputStream, filename).run();
298 } else if(config.isRubiniusEnabled()) {
299 new RubiniusRunner(this, inputStream, filename).run();
300 } else {
301 Node scriptNode = parseFromMain(inputStream, filename);
302 Frame frame = getCurrentContext().getCurrentFrame();
304 frame.setFile(scriptNode.getPosition().getFile());
305 frame.setLine(scriptNode.getPosition().getStartLine());
307 if (config.isAssumePrinting() || config.isAssumeLoop()) {
308 runWithGetsLoop(scriptNode, config.isAssumePrinting(), config.isProcessLineEnds(),
309 config.isSplit(), config.isYARVCompileEnabled());
310 } else {
311 runNormally(scriptNode, config.isYARVCompileEnabled());
317 * Parse the script contained in the given input stream, using the given
318 * filename as the name of the script, and return the root Node. This
319 * is used to verify that the script syntax is valid, for jruby -c. The
320 * current scope (generally the top-level scope) is used as the parent
321 * scope for parsing.
323 * @param inputStream The input stream from which to read the script
324 * @param filename The filename to use for parsing
325 * @returns The root node of the parsed script
327 public Node parseFromMain(InputStream inputStream, String filename) {
328 if (config.isInlineScript()) {
329 return parseInline(inputStream, filename, getCurrentContext().getCurrentScope());
330 } else {
331 return parseFile(inputStream, filename, getCurrentContext().getCurrentScope());
336 * Run the given script with a "while gets; end" loop wrapped around it.
337 * This is primarily used for the -n command-line flag, to allow writing
338 * a short script that processes input lines using the specified code.
340 * @param scriptNode The root node of the script to execute
341 * @param printing Whether $_ should be printed after each loop (as in the
342 * -p command-line flag)
343 * @param processLineEnds Whether line endings should be processed by
344 * setting $\ to $/ and <code>chop!</code>ing every line read
345 * @param split Whether to split each line read using <code>String#split</code>
346 * @param yarvCompile Whether to compile the target script to YARV (Ruby 1.9)
347 * bytecode before executing.
348 * @return The result of executing the specified script
350 public IRubyObject runWithGetsLoop(Node scriptNode, boolean printing, boolean processLineEnds, boolean split, boolean yarvCompile) {
351 ThreadContext context = getCurrentContext();
353 Script script = null;
354 YARVCompiledRunner runner = null;
355 boolean compile = getInstanceConfig().getCompileMode().shouldPrecompileCLI();
356 if (compile || !yarvCompile) {
357 script = tryCompile(scriptNode);
358 if (compile && script == null) {
359 // terminate; tryCompile will have printed out an error and we're done
360 return getNil();
362 } else if (yarvCompile) {
363 runner = tryCompileYarv(scriptNode);
366 if (processLineEnds) {
367 getGlobalVariables().set("$\\", getGlobalVariables().get("$/"));
370 while (RubyKernel.gets(context, getTopSelf(), IRubyObject.NULL_ARRAY).isTrue()) {
371 loop: while (true) { // Used for the 'redo' command
372 try {
373 if (processLineEnds) {
374 getGlobalVariables().get("$_").callMethod(context, "chop!");
377 if (split) {
378 getGlobalVariables().set("$F", getGlobalVariables().get("$_").callMethod(context, "split"));
381 if (script != null) {
382 runScript(script);
383 } else if (runner != null) {
384 runYarv(runner);
385 } else {
386 runInterpreter(scriptNode);
389 if (printing) RubyKernel.print(context, getKernel(), new IRubyObject[] {getGlobalVariables().get("$_")});
390 break loop;
391 } catch (JumpException.RedoJump rj) {
392 // do nothing, this iteration restarts
393 } catch (JumpException.NextJump nj) {
394 // recheck condition
395 break loop;
396 } catch (JumpException.BreakJump bj) {
397 // end loop
398 return (IRubyObject) bj.getValue();
403 return getNil();
407 * Run the specified script without any of the loop-processing wrapper
408 * code.
410 * @param scriptNode The root node of the script to be executed
411 * @param yarvCompile Whether to compile the script to YARV (Ruby 1.9)
412 * bytecode before execution
413 * @return The result of executing the script
415 public IRubyObject runNormally(Node scriptNode, boolean yarvCompile) {
416 Script script = null;
417 YARVCompiledRunner runner = null;
418 boolean compile = getInstanceConfig().getCompileMode().shouldPrecompileCLI();
419 boolean forceCompile = getInstanceConfig().getCompileMode().shouldPrecompileAll();
420 if (compile) {
421 script = tryCompile(scriptNode);
422 if (forceCompile && script == null) {
423 System.err.println("Error, could not compile; pass -J-Djruby.jit.logging.verbose=true for more details");
424 return getNil();
426 } else if (yarvCompile) {
427 runner = tryCompileYarv(scriptNode);
430 if (script != null) {
431 return runScript(script);
432 } else if (runner != null) {
433 return runYarv(runner);
434 } else {
435 return runInterpreter(scriptNode);
439 private Script tryCompile(Node node) {
440 return tryCompile(node, new JRubyClassLoader(getJRubyClassLoader()));
443 private Script tryCompile(Node node, JRubyClassLoader classLoader) {
444 Script script = null;
445 try {
446 String filename = node.getPosition().getFile();
447 String classname = JavaNameMangler.mangledFilenameForStartupClasspath(filename);
449 ASTInspector inspector = new ASTInspector();
450 inspector.inspect(node);
452 StandardASMCompiler asmCompiler = new StandardASMCompiler(classname, filename);
453 ASTCompiler compiler = new ASTCompiler();
454 compiler.compileRoot(node, asmCompiler, inspector);
455 script = (Script)asmCompiler.loadClass(classLoader).newInstance();
457 if (config.isJitLogging()) {
458 System.err.println("compiled: " + node.getPosition().getFile());
460 } catch (NotCompilableException nce) {
461 if (config.isJitLoggingVerbose()) {
462 System.err.println("Error -- Not compileable: " + nce.getMessage());
463 nce.printStackTrace();
465 } catch (ClassNotFoundException e) {
466 if (config.isJitLoggingVerbose()) {
467 System.err.println("Error -- Not compileable: " + e.getMessage());
468 e.printStackTrace();
470 } catch (InstantiationException e) {
471 if (config.isJitLoggingVerbose()) {
472 System.err.println("Error -- Not compileable: " + e.getMessage());
473 e.printStackTrace();
475 } catch (IllegalAccessException e) {
476 if (config.isJitLoggingVerbose()) {
477 System.err.println("Error -- Not compileable: " + e.getMessage());
478 e.printStackTrace();
480 } catch (Throwable t) {
481 if (config.isJitLoggingVerbose()) {
482 System.err.println("could not compile: " + node.getPosition().getFile() + " because of: \"" + t.getMessage() + "\"");
483 t.printStackTrace();
487 return script;
490 private YARVCompiledRunner tryCompileYarv(Node node) {
491 try {
492 StandardYARVCompiler compiler = new StandardYARVCompiler(this);
493 ASTCompiler.getYARVCompiler().compile(node, compiler);
494 org.jruby.lexer.yacc.ISourcePosition p = node.getPosition();
495 if(p == null && node instanceof org.jruby.ast.RootNode) {
496 p = ((org.jruby.ast.RootNode)node).getBodyNode().getPosition();
498 return new YARVCompiledRunner(this,compiler.getInstructionSequence("<main>",p.getFile(),"toplevel"));
499 } catch (NotCompilableException nce) {
500 System.err.println("Error -- Not compileable: " + nce.getMessage());
501 return null;
502 } catch (JumpException.ReturnJump rj) {
503 return null;
507 private IRubyObject runScript(Script script) {
508 ThreadContext context = getCurrentContext();
510 try {
511 return script.load(context, context.getFrameSelf(), IRubyObject.NULL_ARRAY, Block.NULL_BLOCK);
512 } catch (JumpException.ReturnJump rj) {
513 return (IRubyObject) rj.getValue();
517 private IRubyObject runYarv(YARVCompiledRunner runner) {
518 try {
519 return runner.run();
520 } catch (JumpException.ReturnJump rj) {
521 return (IRubyObject) rj.getValue();
525 private IRubyObject runInterpreter(Node scriptNode) {
526 ThreadContext context = getCurrentContext();
528 try {
529 return ASTInterpreter.eval(this, context, scriptNode, getTopSelf(), Block.NULL_BLOCK);
530 } catch (JumpException.ReturnJump rj) {
531 return (IRubyObject) rj.getValue();
536 * @deprecated use #newInstance()
538 public static Ruby getDefaultInstance() {
539 return newInstance();
542 public static Ruby getCurrentInstance() {
543 return currentRuntime.get();
546 public static void setCurrentInstance(Ruby runtime) {
547 currentRuntime.set(runtime);
550 public int allocSymbolId() {
551 return symbolLastId.incrementAndGet();
553 public int allocModuleId() {
554 return moduleLastId.incrementAndGet();
558 * Retrieve the module with the given name from the Object namespace.
560 * @param name The name of the module
561 * @return The module or null if not found
563 public RubyModule getModule(String name) {
564 return (RubyModule) objectClass.getConstantAt(name);
568 * Retrieve the module with the given name from the Object namespace. The
569 * module name must be an interned string, but this method will be faster
570 * than the non-interned version.
572 * @param internedName The name of the module; <em>must</em> be an interned String
573 * @return The module or null if not found
575 public RubyModule fastGetModule(String internedName) {
576 return (RubyModule) objectClass.fastGetConstantAt(internedName);
579 /**
580 * Retrieve the class with the given name from the Object namespace.
582 * @param name The name of the class
583 * @return The class
585 public RubyClass getClass(String name) {
586 return objectClass.getClass(name);
590 * Retrieve the class with the given name from the Object namespace. The
591 * module name must be an interned string, but this method will be faster
592 * than the non-interned version.
594 * @param internedName the name of the class; <em>must</em> be an interned String!
595 * @return
597 public RubyClass fastGetClass(String internedName) {
598 return objectClass.fastGetClass(internedName);
601 /**
602 * Define a new class under the Object namespace. Roughly equivalent to
603 * rb_define_class in MRI.
605 * @param name The name for the new class
606 * @param superClass The super class for the new class
607 * @param allocator An ObjectAllocator instance that can construct
608 * instances of the new class.
609 * @return The new class
611 public RubyClass defineClass(String name, RubyClass superClass, ObjectAllocator allocator) {
612 return defineClassUnder(name, superClass, allocator, objectClass);
616 * Define a new class with the given name under the given module or class
617 * namespace. Roughly equivalent to rb_define_class_under in MRI.
619 * If the name specified is already bound, its value will be returned if:
620 * * It is a class
621 * * No new superclass is being defined
623 * @param name The name for the new class
624 * @param superClass The super class for the new class
625 * @param allocator An ObjectAllocator instance that can construct
626 * instances of the new class.
627 * @param parent The namespace under which to define the new class
628 * @return The new class
630 public RubyClass defineClassUnder(String name, RubyClass superClass, ObjectAllocator allocator, RubyModule parent) {
631 IRubyObject classObj = parent.getConstantAt(name);
633 if (classObj != null) {
634 if (!(classObj instanceof RubyClass)) throw newTypeError(name + " is not a class");
635 RubyClass klazz = (RubyClass)classObj;
636 if (klazz.getSuperClass().getRealClass() != superClass) {
637 throw newNameError(name + " is already defined", name);
639 // If we define a class in Ruby, but later want to allow it to be defined in Java,
640 // the allocator needs to be updated
641 if (klazz.getAllocator() != allocator) {
642 klazz.setAllocator(allocator);
644 return klazz;
647 boolean parentIsObject = parent == objectClass;
649 if (superClass == null) {
650 String className = parentIsObject ? name : parent.getName() + "::" + name;
651 warnings.warn(ID.NO_SUPER_CLASS, "no super class for `" + className + "', Object assumed", className);
653 superClass = objectClass;
656 return RubyClass.newClass(this, superClass, name, allocator, parent, !parentIsObject);
659 /**
660 * Define a new module under the Object namespace. Roughly equivalent to
661 * rb_define_module in MRI.
663 * @param name The name of the new module
664 * @returns The new module
666 public RubyModule defineModule(String name) {
667 return defineModuleUnder(name, objectClass);
671 * Define a new module with the given name under the given module or
672 * class namespace. Roughly equivalent to rb_define_module_under in MRI.
674 * @param name The name of the new module
675 * @param parent The class or module namespace under which to define the
676 * module
677 * @returns The new module
679 public RubyModule defineModuleUnder(String name, RubyModule parent) {
680 IRubyObject moduleObj = parent.getConstantAt(name);
682 boolean parentIsObject = parent == objectClass;
684 if (moduleObj != null ) {
685 if (moduleObj.isModule()) return (RubyModule)moduleObj;
687 if (parentIsObject) {
688 throw newTypeError(moduleObj.getMetaClass().getName() + " is not a module");
689 } else {
690 throw newTypeError(parent.getName() + "::" + moduleObj.getMetaClass().getName() + " is not a module");
694 return RubyModule.newModule(this, name, parent, !parentIsObject);
698 * From Object, retrieve the named module. If it doesn't exist a
699 * new module is created.
701 * @param name The name of the module
702 * @returns The existing or new module
704 public RubyModule getOrCreateModule(String name) {
705 IRubyObject module = objectClass.getConstantAt(name);
706 if (module == null) {
707 module = defineModule(name);
708 } else if (getSafeLevel() >= 4) {
709 throw newSecurityError("Extending module prohibited.");
710 } else if (!module.isModule()) {
711 throw newTypeError(name + " is not a Module");
714 return (RubyModule) module;
718 /**
719 * Retrieve the current safe level.
721 * @see org.jruby.Ruby#setSaveLevel
723 public int getSafeLevel() {
724 return this.safeLevel;
728 /**
729 * Set the current safe level:
731 * 0 - strings from streams/environment/ARGV are tainted (default)
732 * 1 - no dangerous operation by tainted value
733 * 2 - process/file operations prohibited
734 * 3 - all generated objects are tainted
735 * 4 - no global (non-tainted) variable modification/no direct output
737 * The safe level is set using $SAFE in Ruby code. It is not particularly
738 * well supported in JRuby.
740 public void setSafeLevel(int safeLevel) {
741 this.safeLevel = safeLevel;
744 public KCode getKCode() {
745 return kcode;
748 public void setKCode(KCode kcode) {
749 this.kcode = kcode;
752 public void secure(int level) {
753 if (level <= safeLevel) {
754 throw newSecurityError("Insecure operation '" + getCurrentContext().getFrameName() + "' at level " + safeLevel);
758 // FIXME moved this hear to get what's obviously a utility method out of IRubyObject.
759 // perhaps security methods should find their own centralized home at some point.
760 public void checkSafeString(IRubyObject object) {
761 if (getSafeLevel() > 0 && object.isTaint()) {
762 ThreadContext tc = getCurrentContext();
763 if (tc.getFrameName() != null) {
764 throw newSecurityError("Insecure operation - " + tc.getFrameName());
766 throw newSecurityError("Insecure operation: -r");
768 secure(4);
769 if (!(object instanceof RubyString)) {
770 throw newTypeError(
771 "wrong argument type " + object.getMetaClass().getName() + " (expected String)");
775 /** rb_define_global_const
778 public void defineGlobalConstant(String name, IRubyObject value) {
779 objectClass.defineConstant(name, value);
782 public boolean isClassDefined(String name) {
783 return getModule(name) != null;
787 * A ThreadFactory for when we're using pooled threads; we want to create
788 * the threads with daemon = true so they don't keep us from shutting down.
790 public static class DaemonThreadFactory implements ThreadFactory {
791 public Thread newThread(Runnable runnable) {
792 Thread thread = new Thread(runnable);
793 thread.setDaemon(true);
795 return thread;
799 /**
800 * This method is called immediately after constructing the Ruby instance.
801 * The main thread is prepared for execution, all core classes and libraries
802 * are initialized, and any libraries required on the command line are
803 * loaded.
805 private void init() {
806 // Get the main threadcontext (gets constructed for us)
807 ThreadContext tc = getCurrentContext();
809 safeLevel = config.getSafeLevel();
811 // Construct key services
812 loadService = config.createLoadService(this);
813 posix = POSIXFactory.getPOSIX(new JRubyPOSIXHandler(this), RubyInstanceConfig.nativeEnabled);
814 javaSupport = new JavaSupport(this);
816 if (config.POOLING_ENABLED) {
817 Executors.newCachedThreadPool();
818 executor = new ThreadPoolExecutor(
819 RubyInstanceConfig.POOL_MIN,
820 RubyInstanceConfig.POOL_MAX,
821 RubyInstanceConfig.POOL_TTL,
822 TimeUnit.SECONDS,
823 new SynchronousQueue<Runnable>(),
824 new DaemonThreadFactory());
827 // initialize the root of the class hierarchy completely
828 initRoot();
830 // Construct the top-level execution frame and scope for the main thread
831 tc.prepareTopLevel(objectClass, topSelf);
833 // Initialize all the core classes
834 bootstrap();
836 // Create global constants and variables
837 RubyGlobal.createGlobals(this);
839 // Prepare LoadService and load path
840 getLoadService().init(config.loadPaths());
842 // initialize builtin libraries
843 initBuiltins();
845 // Require in all libraries specified on command line
846 for (String scriptName : config.requiredLibraries()) {
847 RubyKernel.require(getTopSelf(), newString(scriptName), Block.NULL_BLOCK);
851 private void bootstrap() {
852 undef = new RubyUndef();
854 initCore();
855 initExceptions();
858 private void initRoot() {
859 // Bootstrap the top of the hierarchy
860 objectClass = RubyClass.createBootstrapClass(this, "Object", null, RubyObject.OBJECT_ALLOCATOR);
861 moduleClass = RubyClass.createBootstrapClass(this, "Module", objectClass, RubyModule.MODULE_ALLOCATOR);
862 classClass = RubyClass.createBootstrapClass(this, "Class", moduleClass, RubyClass.CLASS_ALLOCATOR);
864 objectClass.setMetaClass(classClass);
865 moduleClass.setMetaClass(classClass);
866 classClass.setMetaClass(classClass);
868 RubyClass metaClass;
869 metaClass = objectClass.makeMetaClass(classClass);
870 metaClass = moduleClass.makeMetaClass(metaClass);
871 metaClass = classClass.makeMetaClass(metaClass);
873 RubyObject.createObjectClass(this, objectClass);
874 RubyModule.createModuleClass(this, moduleClass);
875 RubyClass.createClassClass(this, classClass);
877 // set constants now that they're initialized
878 objectClass.setConstant("Object", objectClass);
879 objectClass.setConstant("Class", classClass);
880 objectClass.setConstant("Module", moduleClass);
882 // Initialize Kernel and include into Object
883 RubyKernel.createKernelModule(this);
884 objectClass.includeModule(kernelModule);
886 // Initialize the "dummy" class used as a marker
887 dummyClass = new RubyClass(this);
888 dummyClass.freeze();
890 // Object is ready, create top self
891 topSelf = TopSelfFactory.createTopSelf(this);
894 private void initCore() {
895 // Pre-create all the core classes potentially referenced during startup
896 RubyNil.createNilClass(this);
897 RubyBoolean.createFalseClass(this);
898 RubyBoolean.createTrueClass(this);
900 nilObject = new RubyNil(this);
901 falseObject = new RubyBoolean(this, false);
902 trueObject = new RubyBoolean(this, true);
904 RubyComparable.createComparable(this);
905 RubyEnumerable.createEnumerableModule(this);
906 RubyString.createStringClass(this);
907 RubySymbol.createSymbolClass(this);
909 if (profile.allowClass("ThreadGroup")) {
910 RubyThreadGroup.createThreadGroupClass(this);
912 if (profile.allowClass("Thread")) {
913 RubyThread.createThreadClass(this);
915 if (profile.allowClass("Exception")) {
916 RubyException.createExceptionClass(this);
918 if (profile.allowModule("Precision")) {
919 RubyPrecision.createPrecisionModule(this);
921 if (profile.allowClass("Numeric")) {
922 RubyNumeric.createNumericClass(this);
924 if (profile.allowClass("Integer")) {
925 RubyInteger.createIntegerClass(this);
927 if (profile.allowClass("Fixnum")) {
928 RubyFixnum.createFixnumClass(this);
930 if (profile.allowClass("Hash")) {
931 RubyHash.createHashClass(this);
933 if (profile.allowClass("Array")) {
934 RubyArray.createArrayClass(this);
936 if (profile.allowClass("Float")) {
937 RubyFloat.createFloatClass(this);
939 if (profile.allowClass("Bignum")) {
940 RubyBignum.createBignumClass(this);
942 ioClass = RubyIO.createIOClass(this);
944 if (profile.allowClass("Struct")) {
945 RubyStruct.createStructClass(this);
947 if (profile.allowClass("Tms")) {
948 tmsStruct = RubyStruct.newInstance(structClass, new IRubyObject[]{newString("Tms"), newSymbol("utime"), newSymbol("stime"), newSymbol("cutime"), newSymbol("cstime")}, Block.NULL_BLOCK);
951 if (profile.allowClass("Binding")) {
952 RubyBinding.createBindingClass(this);
954 // Math depends on all numeric types
955 if (profile.allowModule("Math")) {
956 RubyMath.createMathModule(this);
958 if (profile.allowClass("Regexp")) {
959 RubyRegexp.createRegexpClass(this);
961 if (profile.allowClass("Range")) {
962 RubyRange.createRangeClass(this);
964 if (profile.allowModule("ObjectSpace")) {
965 RubyObjectSpace.createObjectSpaceModule(this);
967 if (profile.allowModule("GC")) {
968 RubyGC.createGCModule(this);
970 if (profile.allowClass("Proc")) {
971 RubyProc.createProcClass(this);
973 if (profile.allowClass("Method")) {
974 RubyMethod.createMethodClass(this);
976 if (profile.allowClass("MatchData")) {
977 RubyMatchData.createMatchDataClass(this);
979 if (profile.allowModule("Marshal")) {
980 RubyMarshal.createMarshalModule(this);
982 if (profile.allowClass("Dir")) {
983 RubyDir.createDirClass(this);
985 if (profile.allowModule("FileTest")) {
986 RubyFileTest.createFileTestModule(this);
988 // depends on IO, FileTest
989 if (profile.allowClass("File")) {
990 RubyFile.createFileClass(this);
992 if (profile.allowClass("File::Stat")) {
993 RubyFileStat.createFileStatClass(this);
995 if (profile.allowModule("Process")) {
996 RubyProcess.createProcessModule(this);
998 if (profile.allowClass("Time")) {
999 RubyTime.createTimeClass(this);
1001 if (profile.allowClass("UnboundMethod")) {
1002 RubyUnboundMethod.defineUnboundMethodClass(this);
1004 if (profile.allowClass("Data")) {
1005 defineClass("Data", objectClass, objectClass.getAllocator());
1007 if (!isSecurityRestricted()) {
1008 // Signal uses sun.misc.* classes, this is not allowed
1009 // in the security-sensitive environments
1010 if (profile.allowModule("Signal")) {
1011 RubySignal.createSignal(this);
1014 if (profile.allowClass("Continuation")) {
1015 RubyContinuation.createContinuation(this);
1019 private void initExceptions() {
1020 standardError = defineClassIfAllowed("StandardError", exceptionClass);
1021 runtimeError = defineClassIfAllowed("RuntimeError", standardError);
1022 ioError = defineClassIfAllowed("IOError", standardError);
1023 scriptError = defineClassIfAllowed("ScriptError", exceptionClass);
1024 rangeError = defineClassIfAllowed("RangeError", standardError);
1025 signalException = defineClassIfAllowed("SignalException", exceptionClass);
1027 if (profile.allowClass("NameError")) {
1028 nameError = RubyNameError.createNameErrorClass(this, standardError);
1030 if (profile.allowClass("NoMethodError")) {
1031 RubyNoMethodError.createNoMethodErrorClass(this, nameError);
1033 if (profile.allowClass("SystemExit")) {
1034 RubySystemExit.createSystemExitClass(this, exceptionClass);
1036 if (profile.allowClass("LocalJumpError")) {
1037 RubyLocalJumpError.createLocalJumpErrorClass(this, standardError);
1039 if (profile.allowClass("NativeException")) {
1040 NativeException.createClass(this, runtimeError);
1042 if (profile.allowClass("SystemCallError")) {
1043 systemCallError = RubySystemCallError.createSystemCallErrorClass(this, standardError);
1046 defineClassIfAllowed("Fatal", exceptionClass);
1047 defineClassIfAllowed("Interrupt", signalException);
1048 defineClassIfAllowed("TypeError", standardError);
1049 defineClassIfAllowed("ArgumentError", standardError);
1050 defineClassIfAllowed("IndexError", standardError);
1051 defineClassIfAllowed("SyntaxError", scriptError);
1052 defineClassIfAllowed("LoadError", scriptError);
1053 defineClassIfAllowed("NotImplementedError", scriptError);
1054 defineClassIfAllowed("SecurityError", standardError);
1055 defineClassIfAllowed("NoMemoryError", exceptionClass);
1056 defineClassIfAllowed("RegexpError", standardError);
1057 defineClassIfAllowed("EOFError", ioError);
1058 defineClassIfAllowed("ThreadError", standardError);
1059 defineClassIfAllowed("SystemStackError", standardError);
1060 defineClassIfAllowed("ZeroDivisionError", standardError);
1061 defineClassIfAllowed("FloatDomainError", rangeError);
1063 initErrno();
1066 private RubyClass defineClassIfAllowed(String name, RubyClass superClass) {
1067 // TODO: should probably apply the null object pattern for a
1068 // non-allowed class, rather than null
1069 if (superClass != null && profile.allowClass(name)) {
1070 return defineClass(name, superClass, superClass.getAllocator());
1072 return null;
1075 private Map<Integer, RubyClass> errnos = new HashMap<Integer, RubyClass>();
1077 public RubyClass getErrno(int n) {
1078 return errnos.get(n);
1082 * Create module Errno's Variables. We have this method since Errno does not have it's
1083 * own java class.
1085 private void initErrno() {
1086 if (profile.allowModule("Errno")) {
1087 errnoModule = defineModule("Errno");
1089 Field[] fields = IErrno.class.getFields();
1091 for (int i = 0; i < fields.length; i++) {
1092 try {
1093 createSysErr(fields[i].getInt(IErrno.class), fields[i].getName());
1094 } catch (IllegalAccessException e) {
1095 throw new RuntimeException("Someone defined a non-public constant in IErrno.java", e);
1102 * Creates a system error.
1103 * @param i the error code (will probably use a java exception instead)
1104 * @param name of the error to define.
1106 private void createSysErr(int i, String name) {
1107 if(profile.allowClass(name)) {
1108 RubyClass errno = errnoModule.defineClassUnder(name, systemCallError, systemCallError.getAllocator());
1109 errnos.put(i, errno);
1110 errno.defineConstant("Errno", newFixnum(i));
1114 private void initBuiltins() {
1115 addLazyBuiltin("java.rb", "java", "org.jruby.javasupport.Java");
1116 addLazyBuiltin("jruby.rb", "jruby", "org.jruby.libraries.JRubyLibrary");
1117 addLazyBuiltin("jruby/ext.rb", "jruby/ext", "org.jruby.RubyJRuby$ExtLibrary");
1118 addLazyBuiltin("iconv.rb", "iconv", "org.jruby.libraries.IConvLibrary");
1119 addLazyBuiltin("nkf.rb", "nkf", "org.jruby.libraries.NKFLibrary");
1120 addLazyBuiltin("stringio.rb", "stringio", "org.jruby.libraries.StringIOLibrary");
1121 addLazyBuiltin("strscan.rb", "strscan", "org.jruby.libraries.StringScannerLibrary");
1122 addLazyBuiltin("zlib.rb", "zlib", "org.jruby.libraries.ZlibLibrary");
1123 addLazyBuiltin("yaml_internal.rb", "yaml_internal", "org.jruby.libraries.YamlLibrary");
1124 addLazyBuiltin("enumerator.rb", "enumerator", "org.jruby.libraries.EnumeratorLibrary");
1125 addLazyBuiltin("generator_internal.rb", "generator_internal", "org.jruby.ext.Generator$Service");
1126 addLazyBuiltin("readline.rb", "readline", "org.jruby.ext.Readline$Service");
1127 addLazyBuiltin("thread.so", "thread", "org.jruby.libraries.ThreadLibrary");
1128 addLazyBuiltin("digest.so", "digest", "org.jruby.libraries.DigestLibrary");
1129 addLazyBuiltin("digest.rb", "digest", "org.jruby.libraries.DigestLibrary");
1130 addLazyBuiltin("digest/md5.rb", "digest/md5", "org.jruby.libraries.DigestLibrary$MD5");
1131 addLazyBuiltin("digest/rmd160.rb", "digest/rmd160", "org.jruby.libraries.DigestLibrary$RMD160");
1132 addLazyBuiltin("digest/sha1.rb", "digest/sha1", "org.jruby.libraries.DigestLibrary$SHA1");
1133 addLazyBuiltin("digest/sha2.rb", "digest/sha2", "org.jruby.libraries.DigestLibrary$SHA2");
1134 addLazyBuiltin("bigdecimal.rb", "bigdecimal", "org.jruby.libraries.BigDecimalLibrary");
1135 addLazyBuiltin("io/wait.so", "io/wait", "org.jruby.libraries.IOWaitLibrary");
1136 addLazyBuiltin("etc.so", "etc", "org.jruby.libraries.EtcLibrary");
1137 addLazyBuiltin("weakref.rb", "weakref", "org.jruby.ext.WeakRef$WeakRefLibrary");
1138 addLazyBuiltin("socket.rb", "socket", "org.jruby.ext.socket.RubySocket$Service");
1139 addLazyBuiltin("rbconfig.rb", "rbconfig", "org.jruby.libraries.RbConfigLibrary");
1141 if(RubyInstanceConfig.NATIVE_NET_PROTOCOL) {
1142 addLazyBuiltin("net/protocol.rb", "net/protocol", "org.jruby.libraries.NetProtocolBufferedIOLibrary");
1145 if (config.getCompatVersion() == CompatVersion.RUBY1_9) {
1146 addLazyBuiltin("fiber.so", "fiber", "org.jruby.libraries.FiberLibrary");
1149 addBuiltinIfAllowed("openssl.so", new Library() {
1150 public void load(Ruby runtime, boolean wrap) throws IOException {
1151 runtime.getLoadService().require("jruby/openssl/stub");
1155 String[] builtins = {"fcntl", "yaml", "yaml/syck", "jsignal" };
1156 for (String library : builtins) {
1157 addBuiltinIfAllowed(library + ".rb", new BuiltinScript(library));
1160 getLoadService().require("builtin/core_ext/symbol");
1162 RubyKernel.autoload(topSelf, newSymbol("Java"), newString("java"));
1164 getLoadService().require("enumerator");
1167 private void addLazyBuiltin(String name, String shortName, String className) {
1168 addBuiltinIfAllowed(name, new LateLoadingLibrary(shortName, className, getJRubyClassLoader()));
1171 private void addBuiltinIfAllowed(String name, Library lib) {
1172 if(profile.allowBuiltin(name)) {
1173 loadService.addBuiltinLibrary(name,lib);
1177 Object getRespondToMethod() {
1178 return respondToMethod;
1181 void setRespondToMethod(Object rtm) {
1182 this.respondToMethod = rtm;
1185 public Object getObjectToYamlMethod() {
1186 return objectToYamlMethod;
1189 void setObjectToYamlMethod(Object otym) {
1190 this.objectToYamlMethod = otym;
1194 * Retrieve mappings of cached methods to where they have been cached. When a cached
1195 * method needs to be invalidated this map can be used to remove all places it has been
1196 * cached.
1198 * @return the mappings of where cached methods have been stored
1200 public CacheMap getCacheMap() {
1201 return cacheMap;
1204 /** Getter for property rubyTopSelf.
1205 * @return Value of property rubyTopSelf.
1207 public IRubyObject getTopSelf() {
1208 return topSelf;
1211 public void setCurrentDirectory(String dir) {
1212 currentDirectory = dir;
1215 public String getCurrentDirectory() {
1216 return currentDirectory;
1219 public IRubyObject getUndef() {
1220 return undef;
1223 public RubyModule getEtc() {
1224 return etcModule;
1227 public void setEtc(RubyModule etcModule) {
1228 this.etcModule = etcModule;
1231 public RubyClass getObject() {
1232 return objectClass;
1235 public RubyClass getModule() {
1236 return moduleClass;
1239 public RubyClass getClassClass() {
1240 return classClass;
1243 public RubyModule getKernel() {
1244 return kernelModule;
1246 void setKernel(RubyModule kernelModule) {
1247 this.kernelModule = kernelModule;
1250 public RubyClass getDummy() {
1251 return dummyClass;
1254 public RubyModule getComparable() {
1255 return comparableModule;
1257 void setComparable(RubyModule comparableModule) {
1258 this.comparableModule = comparableModule;
1261 public RubyClass getNumeric() {
1262 return numericClass;
1264 void setNumeric(RubyClass numericClass) {
1265 this.numericClass = numericClass;
1268 public RubyClass getFloat() {
1269 return floatClass;
1271 void setFloat(RubyClass floatClass) {
1272 this.floatClass = floatClass;
1275 public RubyClass getInteger() {
1276 return integerClass;
1278 void setInteger(RubyClass integerClass) {
1279 this.integerClass = integerClass;
1282 public RubyClass getFixnum() {
1283 return fixnumClass;
1285 void setFixnum(RubyClass fixnumClass) {
1286 this.fixnumClass = fixnumClass;
1289 public RubyModule getEnumerable() {
1290 return enumerableModule;
1292 void setEnumerable(RubyModule enumerableModule) {
1293 this.enumerableModule = enumerableModule;
1296 public RubyClass getString() {
1297 return stringClass;
1299 void setString(RubyClass stringClass) {
1300 this.stringClass = stringClass;
1303 public RubyClass getSymbol() {
1304 return symbolClass;
1306 void setSymbol(RubyClass symbolClass) {
1307 this.symbolClass = symbolClass;
1310 public RubyClass getArray() {
1311 return arrayClass;
1313 void setArray(RubyClass arrayClass) {
1314 this.arrayClass = arrayClass;
1317 public RubyClass getHash() {
1318 return hashClass;
1320 void setHash(RubyClass hashClass) {
1321 this.hashClass = hashClass;
1324 public RubyClass getRange() {
1325 return rangeClass;
1327 void setRange(RubyClass rangeClass) {
1328 this.rangeClass = rangeClass;
1331 /** Returns the "true" instance from the instance pool.
1332 * @return The "true" instance.
1334 public RubyBoolean getTrue() {
1335 return trueObject;
1338 /** Returns the "false" instance from the instance pool.
1339 * @return The "false" instance.
1341 public RubyBoolean getFalse() {
1342 return falseObject;
1345 /** Returns the "nil" singleton instance.
1346 * @return "nil"
1348 public IRubyObject getNil() {
1349 return nilObject;
1352 public RubyClass getNilClass() {
1353 return nilClass;
1355 void setNilClass(RubyClass nilClass) {
1356 this.nilClass = nilClass;
1359 public RubyClass getTrueClass() {
1360 return trueClass;
1362 void setTrueClass(RubyClass trueClass) {
1363 this.trueClass = trueClass;
1366 public RubyClass getFalseClass() {
1367 return falseClass;
1369 void setFalseClass(RubyClass falseClass) {
1370 this.falseClass = falseClass;
1373 public RubyClass getProc() {
1374 return procClass;
1376 void setProc(RubyClass procClass) {
1377 this.procClass = procClass;
1380 public RubyClass getBinding() {
1381 return bindingClass;
1383 void setBinding(RubyClass bindingClass) {
1384 this.bindingClass = bindingClass;
1387 public RubyClass getMethod() {
1388 return methodClass;
1390 void setMethod(RubyClass methodClass) {
1391 this.methodClass = methodClass;
1394 public RubyClass getUnboundMethod() {
1395 return unboundMethodClass;
1397 void setUnboundMethod(RubyClass unboundMethodClass) {
1398 this.unboundMethodClass = unboundMethodClass;
1401 public RubyClass getMatchData() {
1402 return matchDataClass;
1404 void setMatchData(RubyClass matchDataClass) {
1405 this.matchDataClass = matchDataClass;
1408 public RubyClass getRegexp() {
1409 return regexpClass;
1411 void setRegexp(RubyClass regexpClass) {
1412 this.regexpClass = regexpClass;
1415 public RubyClass getTime() {
1416 return timeClass;
1418 void setTime(RubyClass timeClass) {
1419 this.timeClass = timeClass;
1422 public RubyModule getMath() {
1423 return mathModule;
1425 void setMath(RubyModule mathModule) {
1426 this.mathModule = mathModule;
1429 public RubyModule getMarshal() {
1430 return marshalModule;
1432 void setMarshal(RubyModule marshalModule) {
1433 this.marshalModule = marshalModule;
1436 public RubyClass getBignum() {
1437 return bignumClass;
1439 void setBignum(RubyClass bignumClass) {
1440 this.bignumClass = bignumClass;
1443 public RubyClass getDir() {
1444 return dirClass;
1446 void setDir(RubyClass dirClass) {
1447 this.dirClass = dirClass;
1450 public RubyClass getFile() {
1451 return fileClass;
1453 void setFile(RubyClass fileClass) {
1454 this.fileClass = fileClass;
1457 public RubyClass getFileStat() {
1458 return fileStatClass;
1460 void setFileStat(RubyClass fileStatClass) {
1461 this.fileStatClass = fileStatClass;
1464 public RubyModule getFileTest() {
1465 return fileTestModule;
1467 void setFileTest(RubyModule fileTestModule) {
1468 this.fileTestModule = fileTestModule;
1471 public RubyClass getIO() {
1472 return ioClass;
1474 void setIO(RubyClass ioClass) {
1475 this.ioClass = ioClass;
1478 public RubyClass getThread() {
1479 return threadClass;
1481 void setThread(RubyClass threadClass) {
1482 this.threadClass = threadClass;
1485 public RubyClass getThreadGroup() {
1486 return threadGroupClass;
1488 void setThreadGroup(RubyClass threadGroupClass) {
1489 this.threadGroupClass = threadGroupClass;
1492 public RubyClass getContinuation() {
1493 return continuationClass;
1495 void setContinuation(RubyClass continuationClass) {
1496 this.continuationClass = continuationClass;
1499 public RubyClass getStructClass() {
1500 return structClass;
1502 void setStructClass(RubyClass structClass) {
1503 this.structClass = structClass;
1506 public IRubyObject getTmsStruct() {
1507 return tmsStruct;
1509 void setTmsStruct(RubyClass tmsStruct) {
1510 this.tmsStruct = tmsStruct;
1513 public IRubyObject getPasswdStruct() {
1514 return passwdStruct;
1516 void setPasswdStruct(RubyClass passwdStruct) {
1517 this.passwdStruct = passwdStruct;
1520 public IRubyObject getGroupStruct() {
1521 return groupStruct;
1523 void setGroupStruct(RubyClass groupStruct) {
1524 this.groupStruct = groupStruct;
1527 public RubyModule getGC() {
1528 return gcModule;
1530 void setGC(RubyModule gcModule) {
1531 this.gcModule = gcModule;
1534 public RubyModule getObjectSpaceModule() {
1535 return objectSpaceModule;
1537 void setObjectSpaceModule(RubyModule objectSpaceModule) {
1538 this.objectSpaceModule = objectSpaceModule;
1541 public RubyModule getProcess() {
1542 return processModule;
1544 void setProcess(RubyModule processModule) {
1545 this.processModule = processModule;
1548 public RubyClass getProcStatus() {
1549 return procStatusClass;
1551 void setProcStatus(RubyClass procStatusClass) {
1552 this.procStatusClass = procStatusClass;
1555 public RubyModule getProcUID() {
1556 return procUIDModule;
1558 void setProcUID(RubyModule procUIDModule) {
1559 this.procUIDModule = procUIDModule;
1562 public RubyModule getProcGID() {
1563 return procGIDModule;
1565 void setProcGID(RubyModule procGIDModule) {
1566 this.procGIDModule = procGIDModule;
1569 public RubyModule getProcSysModule() {
1570 return procSysModule;
1572 void setProcSys(RubyModule procSysModule) {
1573 this.procSysModule = procSysModule;
1576 public RubyModule getPrecision() {
1577 return precisionModule;
1579 void setPrecision(RubyModule precisionModule) {
1580 this.precisionModule = precisionModule;
1583 public RubyClass getException() {
1584 return exceptionClass;
1586 void setException(RubyClass exceptionClass) {
1587 this.exceptionClass = exceptionClass;
1590 public RubyClass getStandardError() {
1591 return standardError;
1594 /** Getter for property isVerbose.
1595 * @return Value of property isVerbose.
1597 public IRubyObject getVerbose() {
1598 return verbose;
1601 /** Setter for property isVerbose.
1602 * @param verbose New value of property isVerbose.
1604 public void setVerbose(IRubyObject verbose) {
1605 this.verbose = verbose;
1608 /** Getter for property isDebug.
1609 * @return Value of property isDebug.
1611 public IRubyObject getDebug() {
1612 return debug;
1615 /** Setter for property isDebug.
1616 * @param debug New value of property isDebug.
1618 public void setDebug(IRubyObject debug) {
1619 this.debug = debug;
1622 public JavaSupport getJavaSupport() {
1623 return javaSupport;
1626 public synchronized JRubyClassLoader getJRubyClassLoader() {
1627 // FIXME: Get rid of laziness and handle restricted access elsewhere
1628 if (!Ruby.isSecurityRestricted() && jrubyClassLoader == null) {
1629 jrubyClassLoader = new JRubyClassLoader(config.getLoader());
1632 return jrubyClassLoader;
1635 /** Defines a global variable
1637 public void defineVariable(final GlobalVariable variable) {
1638 globalVariables.define(variable.name(), new IAccessor() {
1639 public IRubyObject getValue() {
1640 return variable.get();
1643 public IRubyObject setValue(IRubyObject newValue) {
1644 return variable.set(newValue);
1649 /** defines a readonly global variable
1652 public void defineReadonlyVariable(String name, IRubyObject value) {
1653 globalVariables.defineReadonly(name, new ValueAccessor(value));
1656 public Node parseFile(InputStream in, String file, DynamicScope scope) {
1657 return parser.parse(file, in, scope, new ParserConfiguration(0, false, false, true));
1660 public Node parseInline(InputStream in, String file, DynamicScope scope) {
1661 return parser.parse(file, in, scope, new ParserConfiguration(0, false, true));
1664 public Node parseEval(String content, String file, DynamicScope scope, int lineNumber) {
1665 byte[] bytes;
1667 try {
1668 bytes = content.getBytes(KCode.NONE.getKCode());
1669 } catch (UnsupportedEncodingException e) {
1670 bytes = content.getBytes();
1673 return parser.parse(file, new ByteArrayInputStream(bytes), scope,
1674 new ParserConfiguration(lineNumber, false));
1677 public Node parse(String content, String file, DynamicScope scope, int lineNumber,
1678 boolean extraPositionInformation) {
1679 byte[] bytes;
1681 try {
1682 bytes = content.getBytes(KCode.NONE.getKCode());
1683 } catch (UnsupportedEncodingException e) {
1684 bytes = content.getBytes();
1687 return parser.parse(file, new ByteArrayInputStream(bytes), scope,
1688 new ParserConfiguration(lineNumber, extraPositionInformation, false));
1691 public Node parseEval(ByteList content, String file, DynamicScope scope, int lineNumber) {
1692 return parser.parse(file, content, scope, new ParserConfiguration(lineNumber, false));
1695 public Node parse(ByteList content, String file, DynamicScope scope, int lineNumber,
1696 boolean extraPositionInformation) {
1697 return parser.parse(file, content, scope,
1698 new ParserConfiguration(lineNumber, extraPositionInformation, false));
1702 public ThreadService getThreadService() {
1703 return threadService;
1706 public ThreadContext getCurrentContext() {
1707 return threadService.getCurrentContext();
1711 * Returns the loadService.
1712 * @return ILoadService
1714 public LoadService getLoadService() {
1715 return loadService;
1718 public RubyWarnings getWarnings() {
1719 return warnings;
1722 public PrintStream getErrorStream() {
1723 // FIXME: We can't guarantee this will always be a RubyIO...so the old code here is not safe
1724 /*java.io.OutputStream os = ((RubyIO) getGlobalVariables().get("$stderr")).getOutStream();
1725 if(null != os) {
1726 return new PrintStream(os);
1727 } else {
1728 return new PrintStream(new org.jruby.util.SwallowingOutputStream());
1730 return new PrintStream(new IOOutputStream(getGlobalVariables().get("$stderr")));
1733 public InputStream getInputStream() {
1734 return new IOInputStream(getGlobalVariables().get("$stdin"));
1737 public PrintStream getOutputStream() {
1738 return new PrintStream(new IOOutputStream(getGlobalVariables().get("$stdout")));
1741 public RubyModule getClassFromPath(String path) {
1742 RubyModule c = getObject();
1743 if (path.length() == 0 || path.charAt(0) == '#') {
1744 throw newTypeError("can't retrieve anonymous class " + path);
1746 int pbeg = 0, p = 0;
1747 for(int l=path.length(); p<l; ) {
1748 while(p<l && path.charAt(p) != ':') {
1749 p++;
1751 String str = path.substring(pbeg, p);
1753 if(p<l && path.charAt(p) == ':') {
1754 if(p+1 < l && path.charAt(p+1) != ':') {
1755 throw newTypeError("undefined class/module " + path.substring(pbeg,p));
1757 p += 2;
1758 pbeg = p;
1761 IRubyObject cc = c.getConstant(str);
1762 if(!(cc instanceof RubyModule)) {
1763 throw newTypeError("" + path + " does not refer to class/module");
1765 c = (RubyModule)cc;
1767 return c;
1770 /** Prints an error with backtrace to the error stream.
1772 * MRI: eval.c - error_print()
1775 public void printError(RubyException excp) {
1776 if (excp == null || excp.isNil()) {
1777 return;
1780 ThreadContext context = getCurrentContext();
1781 IRubyObject backtrace = excp.callMethod(context, "backtrace");
1783 PrintStream errorStream = getErrorStream();
1784 if (backtrace.isNil() || !(backtrace instanceof RubyArray)) {
1785 if (context.getFile() != null) {
1786 errorStream.print(context.getFile() + ":" + context.getLine());
1787 } else {
1788 errorStream.print(context.getLine());
1790 } else if (((RubyArray) backtrace).getLength() == 0) {
1791 printErrorPos(context, errorStream);
1792 } else {
1793 IRubyObject mesg = ((RubyArray) backtrace).first(IRubyObject.NULL_ARRAY);
1795 if (mesg.isNil()) {
1796 printErrorPos(context, errorStream);
1797 } else {
1798 errorStream.print(mesg);
1802 RubyClass type = excp.getMetaClass();
1803 String info = excp.toString();
1805 if (type == fastGetClass("RuntimeError") && (info == null || info.length() == 0)) {
1806 errorStream.print(": unhandled exception\n");
1807 } else {
1808 String path = type.getName();
1810 if (info.length() == 0) {
1811 errorStream.print(": " + path + '\n');
1812 } else {
1813 if (path.startsWith("#")) {
1814 path = null;
1817 String tail = null;
1818 if (info.indexOf("\n") != -1) {
1819 tail = info.substring(info.indexOf("\n") + 1);
1820 info = info.substring(0, info.indexOf("\n"));
1823 errorStream.print(": " + info);
1825 if (path != null) {
1826 errorStream.print(" (" + path + ")\n");
1829 if (tail != null) {
1830 errorStream.print(tail + '\n');
1835 excp.printBacktrace(errorStream);
1838 private void printErrorPos(ThreadContext context, PrintStream errorStream) {
1839 if (context.getFile() != null) {
1840 if (context.getFrameName() != null) {
1841 errorStream.print(context.getFile() + ":" + context.getLine());
1842 errorStream.print(":in '" + context.getFrameName() + '\'');
1843 } else if (context.getLine() != 0) {
1844 errorStream.print(context.getFile() + ":" + context.getLine());
1845 } else {
1846 errorStream.print(context.getFile());
1851 public void loadFile(String scriptName, InputStream in, boolean wrap) {
1852 if (!Ruby.isSecurityRestricted()) {
1853 File f = new File(scriptName);
1854 if(f.exists() && !f.isAbsolute() && !scriptName.startsWith("./")) {
1855 scriptName = "./" + scriptName;
1859 IRubyObject self = null;
1860 if (wrap) {
1861 self = TopSelfFactory.createTopSelf(this);
1862 } else {
1863 self = getTopSelf();
1865 ThreadContext context = getCurrentContext();
1867 try {
1868 secure(4); /* should alter global state */
1870 context.preNodeEval(objectClass, self, scriptName);
1872 Node node = parseFile(in, scriptName, null);
1873 ASTInterpreter.eval(this, context, node, self, Block.NULL_BLOCK);
1874 } catch (JumpException.ReturnJump rj) {
1875 return;
1876 } finally {
1877 context.postNodeEval();
1881 public void compileAndLoadFile(String filename, InputStream in, boolean wrap) {
1882 IRubyObject self = null;
1883 if (wrap) {
1884 self = TopSelfFactory.createTopSelf(this);
1885 } else {
1886 self = getTopSelf();
1888 ThreadContext context = getCurrentContext();
1890 try {
1891 secure(4); /* should alter global state */
1893 context.preNodeEval(objectClass, self, filename);
1895 Node scriptNode = parseFile(in, filename, null);
1897 Script script = tryCompile(scriptNode, new JRubyClassLoader(jrubyClassLoader));
1898 if (script == null) {
1899 System.err.println("Error, could not compile; pass -J-Djruby.jit.logging.verbose=true for more details");
1902 runScript(script);
1903 } catch (JumpException.ReturnJump rj) {
1904 return;
1905 } finally {
1906 context.postNodeEval();
1910 public void loadScript(Script script) {
1911 IRubyObject self = getTopSelf();
1912 ThreadContext context = getCurrentContext();
1914 try {
1915 secure(4); /* should alter global state */
1917 context.preNodeEval(objectClass, self);
1919 script.load(context, self, IRubyObject.NULL_ARRAY, Block.NULL_BLOCK);
1920 } catch (JumpException.ReturnJump rj) {
1921 return;
1922 } finally {
1923 context.postNodeEval();
1927 public class CallTraceFuncHook implements EventHook {
1928 private RubyProc traceFunc;
1930 public void setTraceFunc(RubyProc traceFunc) {
1931 this.traceFunc = traceFunc;
1934 public void event(ThreadContext context, int event, String file, int line, String name, IRubyObject type) {
1935 if (!context.isWithinTrace()) {
1936 if (file == null) file = "(ruby)";
1937 if (type == null) type = getFalse();
1939 RubyBinding binding = RubyBinding.newBinding(Ruby.this);
1941 context.preTrace();
1942 try {
1943 traceFunc.call(context, new IRubyObject[] {
1944 newString(EVENT_NAMES[event]), // event name
1945 newString(file), // filename
1946 newFixnum(line + 1), // line numbers should be 1-based
1947 name != null ? newSymbol(name) : getNil(),
1948 binding,
1949 type
1951 } finally {
1952 context.postTrace();
1957 public boolean isInterestedInEvent(int event) {
1958 return true;
1962 private final CallTraceFuncHook callTraceFuncHook = new CallTraceFuncHook();
1964 public void addEventHook(EventHook hook) {
1965 eventHooks.add(hook);
1966 hasEventHooks = true;
1969 public void removeEventHook(EventHook hook) {
1970 eventHooks.remove(hook);
1971 hasEventHooks = !eventHooks.isEmpty();
1974 public void setTraceFunction(RubyProc traceFunction) {
1975 removeEventHook(callTraceFuncHook);
1977 if (traceFunction == null) {
1978 return;
1981 callTraceFuncHook.setTraceFunc(traceFunction);
1982 addEventHook(callTraceFuncHook);
1985 public void callEventHooks(ThreadContext context, int event, String file, int line, String name, IRubyObject type) {
1986 for (EventHook eventHook : eventHooks) {
1987 if (eventHook.isInterestedInEvent(event)) {
1988 eventHook.event(context, event, file, line, name, type);
1993 public boolean hasEventHooks() {
1994 return hasEventHooks;
1997 public GlobalVariables getGlobalVariables() {
1998 return globalVariables;
2001 // For JSR 223 support: see http://scripting.java.net/
2002 public void setGlobalVariables(GlobalVariables globalVariables) {
2003 this.globalVariables = globalVariables;
2006 public CallbackFactory callbackFactory(Class<?> type) {
2007 return CallbackFactory.createFactory(this, type);
2011 * Push block onto exit stack. When runtime environment exits
2012 * these blocks will be evaluated.
2014 * @return the element that was pushed onto stack
2016 public IRubyObject pushExitBlock(RubyProc proc) {
2017 atExitBlocks.push(proc);
2018 return proc;
2021 // use this for JRuby-internal finalizers
2022 public void addInternalFinalizer(Finalizable finalizer) {
2023 synchronized (internalFinalizersMutex) {
2024 if (internalFinalizers == null) {
2025 internalFinalizers = new WeakHashMap<Finalizable, Object>();
2027 internalFinalizers.put(finalizer, null);
2031 // this method is for finalizers registered via ObjectSpace
2032 public void addFinalizer(Finalizable finalizer) {
2033 synchronized (finalizersMutex) {
2034 if (finalizers == null) {
2035 finalizers = new WeakHashMap<Finalizable, Object>();
2037 finalizers.put(finalizer, null);
2041 public void removeInternalFinalizer(Finalizable finalizer) {
2042 synchronized (internalFinalizersMutex) {
2043 if (internalFinalizers != null) {
2044 internalFinalizers.remove(finalizer);
2049 public void removeFinalizer(Finalizable finalizer) {
2050 synchronized (finalizersMutex) {
2051 if (finalizers != null) {
2052 finalizers.remove(finalizer);
2058 * Make sure Kernel#at_exit procs get invoked on runtime shutdown.
2059 * This method needs to be explicitly called to work properly.
2060 * I thought about using finalize(), but that did not work and I
2061 * am not sure the runtime will be at a state to run procs by the
2062 * time Ruby is going away. This method can contain any other
2063 * things that need to be cleaned up at shutdown.
2065 public void tearDown() {
2066 while (!atExitBlocks.empty()) {
2067 RubyProc proc = atExitBlocks.pop();
2069 proc.call(proc.getRuntime().getCurrentContext(), IRubyObject.NULL_ARRAY);
2071 if (finalizers != null) {
2072 synchronized (finalizers) {
2073 for (Iterator<Finalizable> finalIter = new ArrayList<Finalizable>(finalizers.keySet()).iterator(); finalIter.hasNext();) {
2074 finalIter.next().finalize();
2075 finalIter.remove();
2080 synchronized (internalFinalizersMutex) {
2081 if (internalFinalizers != null) {
2082 for (Iterator<Finalizable> finalIter = new ArrayList<Finalizable>(
2083 internalFinalizers.keySet()).iterator(); finalIter.hasNext();) {
2084 finalIter.next().finalize();
2085 finalIter.remove();
2089 getThreadService().disposeCurrentThread();
2092 // new factory methods ------------------------------------------------------------------------
2094 public RubyArray newEmptyArray() {
2095 return RubyArray.newEmptyArray(this);
2098 public RubyArray newArray() {
2099 return RubyArray.newArray(this);
2102 public RubyArray newArrayLight() {
2103 return RubyArray.newArrayLight(this);
2106 public RubyArray newArray(IRubyObject object) {
2107 return RubyArray.newArray(this, object);
2110 public RubyArray newArray(IRubyObject car, IRubyObject cdr) {
2111 return RubyArray.newArray(this, car, cdr);
2114 public RubyArray newArray(IRubyObject[] objects) {
2115 return RubyArray.newArray(this, objects);
2118 public RubyArray newArrayNoCopy(IRubyObject[] objects) {
2119 return RubyArray.newArrayNoCopy(this, objects);
2122 public RubyArray newArrayNoCopyLight(IRubyObject[] objects) {
2123 return RubyArray.newArrayNoCopyLight(this, objects);
2126 public RubyArray newArray(List<IRubyObject> list) {
2127 return RubyArray.newArray(this, list);
2130 public RubyArray newArray(int size) {
2131 return RubyArray.newArray(this, size);
2134 public RubyBoolean newBoolean(boolean value) {
2135 return RubyBoolean.newBoolean(this, value);
2138 public RubyFileStat newFileStat(String filename, boolean lstat) {
2139 return RubyFileStat.newFileStat(this, filename, lstat);
2142 public RubyFileStat newFileStat(FileDescriptor descriptor) {
2143 return RubyFileStat.newFileStat(this, descriptor);
2146 public RubyFixnum newFixnum(long value) {
2147 return RubyFixnum.newFixnum(this, value);
2150 public RubyFloat newFloat(double value) {
2151 return RubyFloat.newFloat(this, value);
2154 public RubyNumeric newNumeric() {
2155 return RubyNumeric.newNumeric(this);
2158 public RubyProc newProc(Block.Type type, Block block) {
2159 if (type != Block.Type.LAMBDA && block.getProcObject() != null) return block.getProcObject();
2161 RubyProc proc = RubyProc.newProc(this, type);
2163 proc.callInit(IRubyObject.NULL_ARRAY, block);
2165 return proc;
2168 public RubyBinding newBinding() {
2169 return RubyBinding.newBinding(this);
2172 public RubyBinding newBinding(Binding binding) {
2173 return RubyBinding.newBinding(this, binding);
2176 public RubyString newString() {
2177 return RubyString.newString(this, "");
2180 public RubyString newString(String string) {
2181 return RubyString.newString(this, string);
2184 public RubyString newString(ByteList byteList) {
2185 return RubyString.newString(this, byteList);
2188 public RubyString newStringShared(ByteList byteList) {
2189 return RubyString.newStringShared(this, byteList);
2192 public RubySymbol newSymbol(String name) {
2193 return symbolTable.getSymbol(name);
2197 * Faster than {@link #newSymbol(String)} if you already have an interned
2198 * name String. Don't intern your string just to call this version - the
2199 * overhead of interning will more than wipe out any benefit from the faster
2200 * lookup.
2202 * @param internedName the symbol name, <em>must</em> be interned! if in
2203 * doubt, call {@link #newSymbol(String)} instead.
2204 * @return the symbol for name
2206 public RubySymbol fastNewSymbol(String internedName) {
2207 assert internedName == internedName.intern() : internedName + " is not interned";
2209 return symbolTable.fastGetSymbol(internedName);
2212 public RubyTime newTime(long milliseconds) {
2213 return RubyTime.newTime(this, milliseconds);
2216 public RaiseException newRuntimeError(String message) {
2217 return newRaiseException(fastGetClass("RuntimeError"), message);
2220 public RaiseException newArgumentError(String message) {
2221 return newRaiseException(fastGetClass("ArgumentError"), message);
2224 public RaiseException newArgumentError(int got, int expected) {
2225 return newRaiseException(fastGetClass("ArgumentError"), "wrong # of arguments(" + got + " for " + expected + ")");
2228 public RaiseException newErrnoEBADFError() {
2229 return newRaiseException(fastGetModule("Errno").fastGetClass("EBADF"), "Bad file descriptor");
2232 public RaiseException newErrnoENOPROTOOPTError() {
2233 return newRaiseException(fastGetModule("Errno").fastGetClass("ENOPROTOOPT"), "Protocol not available");
2236 public RaiseException newErrnoEPIPEError() {
2237 return newRaiseException(fastGetModule("Errno").fastGetClass("EPIPE"), "Broken pipe");
2240 public RaiseException newErrnoECONNREFUSEDError() {
2241 return newRaiseException(fastGetModule("Errno").fastGetClass("ECONNREFUSED"), "Connection refused");
2244 public RaiseException newErrnoEADDRINUSEError() {
2245 return newRaiseException(fastGetModule("Errno").fastGetClass("EADDRINUSE"), "Address in use");
2248 public RaiseException newErrnoEINVALError() {
2249 return newRaiseException(fastGetModule("Errno").fastGetClass("EINVAL"), "Invalid file");
2252 public RaiseException newErrnoENOENTError() {
2253 return newRaiseException(fastGetModule("Errno").fastGetClass("ENOENT"), "File not found");
2256 public RaiseException newErrnoEACCESError(String message) {
2257 return newRaiseException(
2258 fastGetModule("Errno").fastGetClass("EACCES"), message);
2261 public RaiseException newErrnoEAGAINError(String message) {
2262 return newRaiseException(
2263 fastGetModule("Errno").fastGetClass("EAGAIN"), message);
2266 public RaiseException newErrnoEISDirError() {
2267 return newRaiseException(fastGetModule("Errno").fastGetClass("EISDIR"), "Is a directory");
2270 public RaiseException newErrnoESPIPEError() {
2271 return newRaiseException(fastGetModule("Errno").fastGetClass("ESPIPE"), "Illegal seek");
2274 public RaiseException newErrnoEBADFError(String message) {
2275 return newRaiseException(fastGetModule("Errno").fastGetClass("EBADF"), message);
2278 public RaiseException newErrnoEINVALError(String message) {
2279 return newRaiseException(fastGetModule("Errno").fastGetClass("EINVAL"), message);
2282 public RaiseException newErrnoENOTDIRError(String message) {
2283 return newRaiseException(fastGetModule("Errno").fastGetClass("ENOTDIR"), message);
2286 public RaiseException newErrnoENOENTError(String message) {
2287 return newRaiseException(fastGetModule("Errno").fastGetClass("ENOENT"), message);
2290 public RaiseException newErrnoESPIPEError(String message) {
2291 return newRaiseException(fastGetModule("Errno").fastGetClass("ESPIPE"), message);
2294 public RaiseException newErrnoEEXISTError(String message) {
2295 return newRaiseException(fastGetModule("Errno").fastGetClass("EEXIST"), message);
2298 public RaiseException newErrnoEDOMError(String message) {
2299 return newRaiseException(fastGetModule("Errno").fastGetClass("EDOM"), "Domain error - " + message);
2302 public RaiseException newErrnoECHILDError() {
2303 return newRaiseException(fastGetModule("Errno").fastGetClass("ECHILD"), "No child processes");
2306 public RaiseException newIndexError(String message) {
2307 return newRaiseException(fastGetClass("IndexError"), message);
2310 public RaiseException newSecurityError(String message) {
2311 return newRaiseException(fastGetClass("SecurityError"), message);
2314 public RaiseException newSystemCallError(String message) {
2315 return newRaiseException(fastGetClass("SystemCallError"), message);
2318 public RaiseException newTypeError(String message) {
2319 return newRaiseException(fastGetClass("TypeError"), message);
2322 public RaiseException newThreadError(String message) {
2323 return newRaiseException(fastGetClass("ThreadError"), message);
2326 public RaiseException newSyntaxError(String message) {
2327 return newRaiseException(fastGetClass("SyntaxError"), message);
2330 public RaiseException newRegexpError(String message) {
2331 return newRaiseException(fastGetClass("RegexpError"), message);
2334 public RaiseException newRangeError(String message) {
2335 return newRaiseException(fastGetClass("RangeError"), message);
2338 public RaiseException newNotImplementedError(String message) {
2339 return newRaiseException(fastGetClass("NotImplementedError"), message);
2342 public RaiseException newInvalidEncoding(String message) {
2343 return newRaiseException(fastGetClass("Iconv").fastGetClass("InvalidEncoding"), message);
2346 public RaiseException newNoMethodError(String message, String name, IRubyObject args) {
2347 return new RaiseException(new RubyNoMethodError(this, this.fastGetClass("NoMethodError"), message, name, args), true);
2350 public RaiseException newNameError(String message, String name) {
2351 return newNameError(message, name, null);
2354 public RaiseException newNameError(String message, String name, Throwable origException) {
2355 return newNameError(message, name, origException, true);
2358 public RaiseException newNameError(String message, String name, Throwable origException, boolean printWhenVerbose) {
2359 if (printWhenVerbose && origException != null && this.getVerbose().isTrue()) {
2360 origException.printStackTrace(getErrorStream());
2362 return new RaiseException(new RubyNameError(
2363 this, this.fastGetClass("NameError"), message, name), true);
2366 public RaiseException newLocalJumpError(String reason, IRubyObject exitValue, String message) {
2367 return new RaiseException(new RubyLocalJumpError(this, fastGetClass("LocalJumpError"), message, reason, exitValue), true);
2370 public RaiseException newRedoLocalJumpError() {
2371 return new RaiseException(new RubyLocalJumpError(this, fastGetClass("LocalJumpError"), "unexpected redo", "redo", getNil()), true);
2374 public RaiseException newLoadError(String message) {
2375 return newRaiseException(fastGetClass("LoadError"), message);
2378 public RaiseException newFrozenError(String objectType) {
2379 // TODO: Should frozen error have its own distinct class? If not should more share?
2380 return newRaiseException(fastGetClass("TypeError"), "can't modify frozen " + objectType);
2383 public RaiseException newSystemStackError(String message) {
2384 return newRaiseException(fastGetClass("SystemStackError"), message);
2387 public RaiseException newSystemExit(int status) {
2388 return new RaiseException(RubySystemExit.newInstance(this, status));
2391 public RaiseException newIOError(String message) {
2392 return newRaiseException(fastGetClass("IOError"), message);
2395 public RaiseException newStandardError(String message) {
2396 return newRaiseException(fastGetClass("StandardError"), message);
2399 public RaiseException newIOErrorFromException(IOException ioe) {
2400 return newRaiseException(fastGetClass("IOError"), ioe.getMessage());
2403 public RaiseException newTypeError(IRubyObject receivedObject, RubyClass expectedType) {
2404 return newRaiseException(fastGetClass("TypeError"), "wrong argument type " +
2405 receivedObject.getMetaClass().getRealClass() + " (expected " + expectedType + ")");
2408 public RaiseException newEOFError() {
2409 return newRaiseException(fastGetClass("EOFError"), "End of file reached");
2412 public RaiseException newEOFError(String message) {
2413 return newRaiseException(fastGetClass("EOFError"), message);
2416 public RaiseException newZeroDivisionError() {
2417 return newRaiseException(fastGetClass("ZeroDivisionError"), "divided by 0");
2420 public RaiseException newFloatDomainError(String message){
2421 return newRaiseException(fastGetClass("FloatDomainError"), message);
2425 * @param exceptionClass
2426 * @param message
2427 * @return
2429 private RaiseException newRaiseException(RubyClass exceptionClass, String message) {
2430 RaiseException re = new RaiseException(this, exceptionClass, message, true);
2431 return re;
2435 public RubySymbol.SymbolTable getSymbolTable() {
2436 return symbolTable;
2439 public void setStackTraces(int stackTraces) {
2440 this.stackTraces = stackTraces;
2443 public int getStackTraces() {
2444 return stackTraces;
2447 public void setRandomSeed(long randomSeed) {
2448 this.randomSeed = randomSeed;
2451 public long getRandomSeed() {
2452 return randomSeed;
2455 public Random getRandom() {
2456 return random;
2459 public ObjectSpace getObjectSpace() {
2460 return objectSpace;
2463 public Map<Integer, WeakReference<ChannelDescriptor>> getDescriptors() {
2464 return descriptors;
2467 public long incrementRandomSeedSequence() {
2468 return randomSeedSequence++;
2471 public InputStream getIn() {
2472 return in;
2475 public PrintStream getOut() {
2476 return out;
2479 public PrintStream getErr() {
2480 return err;
2483 public boolean isGlobalAbortOnExceptionEnabled() {
2484 return globalAbortOnExceptionEnabled;
2487 public void setGlobalAbortOnExceptionEnabled(boolean enable) {
2488 globalAbortOnExceptionEnabled = enable;
2491 public boolean isDoNotReverseLookupEnabled() {
2492 return doNotReverseLookupEnabled;
2495 public void setDoNotReverseLookupEnabled(boolean b) {
2496 doNotReverseLookupEnabled = b;
2499 private ThreadLocal<Map<Object, Object>> inspect = new ThreadLocal<Map<Object, Object>>();
2500 public void registerInspecting(Object obj) {
2501 Map<Object, Object> val = inspect.get();
2502 if (val == null) inspect.set(val = new IdentityHashMap<Object, Object>());
2503 val.put(obj, null);
2506 public boolean isInspecting(Object obj) {
2507 Map<Object, Object> val = inspect.get();
2508 return val == null ? false : val.containsKey(obj);
2511 public void unregisterInspecting(Object obj) {
2512 Map<Object, Object> val = inspect.get();
2513 if (val != null ) val.remove(obj);
2516 public boolean isObjectSpaceEnabled() {
2517 return objectSpaceEnabled;
2520 // The method is intentionally not public, since it typically should
2521 // not be used outside of the core.
2522 /* package-private */ void setObjectSpaceEnabled(boolean objectSpaceEnabled) {
2523 this.objectSpaceEnabled = objectSpaceEnabled;
2526 public long getStartTime() {
2527 return startTime;
2530 public Profile getProfile() {
2531 return profile;
2534 public String getJRubyHome() {
2535 return config.getJRubyHome();
2538 public void setJRubyHome(String home) {
2539 config.setJRubyHome(home);
2542 public RubyInstanceConfig getInstanceConfig() {
2543 return config;
2546 /** GET_VM_STATE_VERSION */
2547 public long getGlobalState() {
2548 synchronized(this) {
2549 return globalState;
2553 /** INC_VM_STATE_VERSION */
2554 public void incGlobalState() {
2555 synchronized(this) {
2556 globalState = (globalState+1) & 0x8fffffff;
2560 public static boolean isSecurityRestricted() {
2561 return securityRestricted;
2564 public static void setSecurityRestricted(boolean restricted) {
2565 securityRestricted = restricted;
2568 public POSIX getPosix() {
2569 return posix;
2572 public void setRecordSeparatorVar(GlobalVariable recordSeparatorVar) {
2573 this.recordSeparatorVar = recordSeparatorVar;
2576 public GlobalVariable getRecordSeparatorVar() {
2577 return recordSeparatorVar;
2580 public Set<Script> getJittedMethods() {
2581 return jittedMethods;
2584 public ExecutorService getExecutor() {
2585 return executor;
2588 private CacheMap cacheMap = new CacheMap();
2589 private ThreadService threadService;
2590 private Hashtable<Object, Object> runtimeInformation;
2592 private POSIX posix;
2594 private int stackTraces = 0;
2596 private ObjectSpace objectSpace = new ObjectSpace();
2598 private final RubySymbol.SymbolTable symbolTable = new RubySymbol.SymbolTable(this);
2599 private Map<Integer, WeakReference<ChannelDescriptor>> descriptors = new ConcurrentHashMap<Integer, WeakReference<ChannelDescriptor>>();
2600 private long randomSeed = 0;
2601 private long randomSeedSequence = 0;
2602 private Random random = new Random();
2604 private List<EventHook> eventHooks = new Vector<EventHook>();
2605 private boolean hasEventHooks;
2606 private boolean globalAbortOnExceptionEnabled = false;
2607 private boolean doNotReverseLookupEnabled = false;
2608 private volatile boolean objectSpaceEnabled;
2610 private final Set<Script> jittedMethods = Collections.synchronizedSet(new WeakHashSet<Script>());
2612 private static ThreadLocal<Ruby> currentRuntime = new ThreadLocal<Ruby>();
2613 public static final boolean RUNTIME_THREADLOCAL
2614 = SafePropertyAccessor.getBoolean("jruby.runtime.threadlocal");
2616 private long globalState = 1;
2618 private int safeLevel = -1;
2620 // Default objects
2621 private IRubyObject undef;
2622 private IRubyObject topSelf;
2623 private RubyNil nilObject;
2624 private RubyBoolean trueObject;
2625 private RubyBoolean falseObject;
2626 public final RubyFixnum[] fixnumCache = new RubyFixnum[256];
2628 private IRubyObject verbose;
2629 private IRubyObject debug;
2632 * All the core classes we keep hard references to. These are here largely
2633 * so that if someone redefines String or Array we won't start blowing up
2634 * creating strings and arrays internally. They also provide much faster
2635 * access than going through normal hash lookup on the Object class.
2637 private RubyClass
2638 objectClass, moduleClass, classClass, nilClass, trueClass,
2639 falseClass, numericClass, floatClass, integerClass, fixnumClass,
2640 arrayClass, hashClass, rangeClass, stringClass, symbolClass,
2641 procClass, bindingClass, methodClass, unboundMethodClass,
2642 matchDataClass, regexpClass, timeClass, bignumClass, dirClass,
2643 fileClass, fileStatClass, ioClass, threadClass, threadGroupClass,
2644 continuationClass, structClass, tmsStruct, passwdStruct,
2645 groupStruct, procStatusClass, exceptionClass, runtimeError, ioError,
2646 scriptError, nameError, signalException, standardError,
2647 systemCallError, rangeError, dummyClass;
2650 * All the core modules we keep direct references to, for quick access and
2651 * to ensure they remain available.
2653 private RubyModule
2654 kernelModule, comparableModule, enumerableModule, mathModule,
2655 marshalModule, etcModule, fileTestModule, gcModule,
2656 objectSpaceModule, processModule, procUIDModule, procGIDModule,
2657 procSysModule, precisionModule, errnoModule;
2659 // record separator var, to speed up io ops that use it
2660 private GlobalVariable recordSeparatorVar;
2662 // former java.lang.System concepts now internalized for MVM
2663 private String currentDirectory;
2665 private long startTime = System.currentTimeMillis();
2667 private RubyInstanceConfig config;
2669 private InputStream in;
2670 private PrintStream out;
2671 private PrintStream err;
2673 // Java support
2674 private JavaSupport javaSupport;
2675 private JRubyClassLoader jrubyClassLoader;
2677 // Note: this field and the following static initializer
2678 // must be located be in this order!
2679 private volatile static boolean securityRestricted = false;
2680 static {
2681 if (SafePropertyAccessor.isSecurityProtected("jruby.reflection")) {
2682 // can't read non-standard properties
2683 securityRestricted = true;
2684 } else {
2685 SecurityManager sm = System.getSecurityManager();
2686 if (sm != null) {
2687 try {
2688 sm.checkCreateClassLoader();
2689 } catch (SecurityException se) {
2690 // can't create custom classloaders
2691 securityRestricted = true;
2697 private Parser parser = new Parser(this);
2699 private LoadService loadService;
2700 private GlobalVariables globalVariables = new GlobalVariables(this);
2701 private RubyWarnings warnings = new RubyWarnings(this);
2703 // Contains a list of all blocks (as Procs) that should be called when
2704 // the runtime environment exits.
2705 private Stack<RubyProc> atExitBlocks = new Stack<RubyProc>();
2707 private Profile profile;
2709 private KCode kcode = KCode.NONE;
2711 // Atomic integers for symbol and method IDs
2712 private AtomicInteger symbolLastId = new AtomicInteger(128);
2713 private AtomicInteger moduleLastId = new AtomicInteger(0);
2715 private Object respondToMethod;
2716 private Object objectToYamlMethod;
2719 * A list of "external" finalizers (the ones, registered via ObjectSpace),
2720 * weakly referenced, to be executed on tearDown.
2722 private Map<Finalizable, Object> finalizers;
2725 * A list of JRuby-internal finalizers, weakly referenced,
2726 * to be executed on tearDown.
2728 private Map<Finalizable, Object> internalFinalizers;
2730 // mutex that controls modifications of user-defined finalizers
2731 private final Object finalizersMutex = new Object();
2733 // mutex that controls modifications of internal finalizers
2734 private final Object internalFinalizersMutex = new Object();
2736 // A thread pool to use for executing this runtime's Ruby threads
2737 private ExecutorService executor;