This repository is private.
All pages are served over SSL and all pushing and pulling is done over SSH.
No one may fork, clone, or view it unless they are added as a member.
Every repository with this icon (
) is private.
Every repository with this icon (
This repository is public.
Anyone may fork, clone, or view it.
Every repository with this icon (
) is public.
Every repository with this icon (
clustered-jruby / clustering_jruby.patch
| d7e19b4f » | fabiokung | 2008-11-22 | 1 | Index: src/org/jruby/runtime/ReadonlyGlobalVariable.java | |
| 2 | =================================================================== | ||||
| 3 | --- src/org/jruby/runtime/ReadonlyGlobalVariable.java (revision 8091) | ||||
| 4 | +++ src/org/jruby/runtime/ReadonlyGlobalVariable.java (working copy) | ||||
| 5 | @@ -34,12 +34,12 @@ | ||||
| 6 | |||||
| 7 | public class ReadonlyGlobalVariable extends GlobalVariable { | ||||
| 8 | |||||
| 9 | - public ReadonlyGlobalVariable(Ruby runtime, String name, IRubyObject value) { | ||||
| 10 | - super(runtime, name, value); | ||||
| 11 | + public ReadonlyGlobalVariable(String name, IRubyObject value) { | ||||
| 12 | + super(name, value); | ||||
| 13 | } | ||||
| 14 | |||||
| 15 | @Override | ||||
| 16 | public IRubyObject set(IRubyObject value) { | ||||
| 17 | - throw runtime.newNameError(name() + " is a read-only variable", name()); | ||||
| 18 | + throw Ruby.getCurrentRuntime().newNameError(name() + " is a read-only variable", name()); | ||||
| 19 | } | ||||
| 20 | } | ||||
| 21 | Index: src/org/jruby/runtime/GlobalVariable.java | ||||
| 22 | =================================================================== | ||||
| 23 | --- src/org/jruby/runtime/GlobalVariable.java (revision 8091) | ||||
| 24 | +++ src/org/jruby/runtime/GlobalVariable.java (working copy) | ||||
| 25 | @@ -39,7 +39,7 @@ | ||||
| 26 | private GlobalVariable other; | ||||
| 27 | |||||
| 28 | public Copy(Ruby runtime, String name, GlobalVariable other) { | ||||
| 29 | - super(runtime, name, other.get()); | ||||
| 30 | + super(name, other.get()); | ||||
| 31 | this.other = other; | ||||
| 32 | } | ||||
| 33 | |||||
| 34 | @@ -54,8 +54,6 @@ | ||||
| 35 | } | ||||
| 36 | } | ||||
| 37 | |||||
| 38 | - protected final Ruby runtime; | ||||
| 39 | - | ||||
| 40 | protected final String name; | ||||
| 41 | private IRubyObject value; | ||||
| 42 | |||||
| 43 | @@ -63,10 +61,8 @@ | ||||
| 44 | return "$" + name; | ||||
| 45 | } | ||||
| 46 | |||||
| 47 | - public GlobalVariable(Ruby runtime, String name, IRubyObject value) { | ||||
| 48 | + public GlobalVariable(String name, IRubyObject value) { | ||||
| 49 | assert name.startsWith("$"); | ||||
| 50 | - | ||||
| 51 | - this.runtime = runtime; | ||||
| 52 | this.name = name; | ||||
| 53 | this.value = value; | ||||
| 54 | } | ||||
| 55 | Index: src/org/jruby/runtime/GlobalVariableAcessor.java | ||||
| 56 | =================================================================== | ||||
| 57 | --- src/org/jruby/runtime/GlobalVariableAcessor.java (revision 0) | ||||
| 58 | +++ src/org/jruby/runtime/GlobalVariableAcessor.java (revision 0) | ||||
| 59 | @@ -0,0 +1,24 @@ | ||||
| 60 | +package org.jruby.runtime; | ||||
| 61 | + | ||||
| 62 | +import org.jruby.runtime.IAccessor; | ||||
| 63 | +import org.jruby.runtime.GlobalVariable; | ||||
| 64 | +import org.jruby.runtime.builtin.IRubyObject; | ||||
| 65 | + | ||||
| 66 | +/** | ||||
| 67 | + * @author Fabio Kung | ||||
| 68 | +*/ | ||||
| 69 | +public class GlobalVariableAcessor implements IAccessor { | ||||
| 70 | + private final GlobalVariable variable; | ||||
| 71 | + | ||||
| 72 | + public GlobalVariableAcessor(GlobalVariable variable) { | ||||
| 73 | + this.variable = variable; | ||||
| 74 | + } | ||||
| 75 | + | ||||
| 76 | + public IRubyObject getValue() { | ||||
| 77 | + return variable.get(); | ||||
| 78 | + } | ||||
| 79 | + | ||||
| 80 | + public IRubyObject setValue(IRubyObject newValue) { | ||||
| 81 | + return variable.set(newValue); | ||||
| 82 | + } | ||||
| 83 | +} | ||||
| 84 | Index: src/org/jruby/ext/ffi/io/FileDescriptorIO.java | ||||
| 85 | =================================================================== | ||||
| 86 | --- src/org/jruby/ext/ffi/io/FileDescriptorIO.java (revision 8091) | ||||
| 87 | +++ src/org/jruby/ext/ffi/io/FileDescriptorIO.java (working copy) | ||||
| 88 | @@ -68,7 +68,7 @@ | ||||
| 89 | } catch (InvalidValueException ex) { | ||||
| 90 | throw new RuntimeException(ex); | ||||
| 91 | } | ||||
| 92 | - openFile.setMainStream(new ChannelStream(getRuntime(), | ||||
| 93 | + openFile.setMainStream(new ChannelStream( | ||||
| 94 | new ChannelDescriptor(Factory.getInstance().newByteChannel(RubyNumeric.fix2int(fd)), | ||||
| 95 | getNewFileno(), modes, new java.io.FileDescriptor()))); | ||||
| 96 | openFile.setPipeStream(openFile.getMainStream()); | ||||
| 97 | Index: src/org/jruby/ext/socket/RubyUNIXSocket.java | ||||
| 98 | =================================================================== | ||||
| 99 | --- src/org/jruby/ext/socket/RubyUNIXSocket.java (revision 8091) | ||||
| 100 | +++ src/org/jruby/ext/socket/RubyUNIXSocket.java (working copy) | ||||
| 101 | @@ -311,7 +311,7 @@ | ||||
| 102 | |||||
| 103 | protected void init_sock(Ruby runtime) throws Exception { | ||||
| 104 | ModeFlags modes = new ModeFlags(ModeFlags.RDWR); | ||||
| 105 | - openFile.setMainStream(new ChannelStream(runtime, new ChannelDescriptor(new UnixDomainSocketChannel(fd), getNewFileno(), modes, new java.io.FileDescriptor()))); | ||||
| 106 | + openFile.setMainStream(new ChannelStream(new ChannelDescriptor(new UnixDomainSocketChannel(fd), getNewFileno(), modes, new java.io.FileDescriptor()))); | ||||
| 107 | openFile.setPipeStream(openFile.getMainStream()); | ||||
| 108 | openFile.setMode(modes.getOpenFileFlags()); | ||||
| 109 | openFile.getMainStream().setSync(true); | ||||
| 110 | Index: src/org/jruby/internal/runtime/GlobalVariables.java | ||||
| 111 | =================================================================== | ||||
| 112 | --- src/org/jruby/internal/runtime/GlobalVariables.java (revision 8091) | ||||
| 113 | +++ src/org/jruby/internal/runtime/GlobalVariables.java (working copy) | ||||
| 114 | @@ -47,13 +47,8 @@ | ||||
| 115 | * @author jpetersen | ||||
| 116 | */ | ||||
| 117 | public class GlobalVariables { | ||||
| 118 | - private Ruby runtime; | ||||
| 119 | private Map<String, GlobalVariable> globalVariables = new ConcurrentHashMap<String, GlobalVariable>(); | ||||
| 120 | |||||
| 121 | - public GlobalVariables(Ruby runtime) { | ||||
| 122 | - this.runtime = runtime; | ||||
| 123 | - } | ||||
| 124 | - | ||||
| 125 | public void define(String name, IAccessor accessor) { | ||||
| 126 | assert name != null; | ||||
| 127 | assert accessor != null; | ||||
| 128 | @@ -89,15 +84,16 @@ | ||||
| 129 | assert name.startsWith("$"); | ||||
| 130 | assert oldName.startsWith("$"); | ||||
| 131 | |||||
| 132 | - if (runtime.getSafeLevel() >= 4) { | ||||
| 133 | - throw runtime.newSecurityError("Insecure: can't alias global variable"); | ||||
| 134 | + if (Ruby.getCurrentRuntime().getSafeLevel() >= 4) { | ||||
| 135 | + throw Ruby.getCurrentRuntime().newSecurityError("Insecure: can't alias global variable"); | ||||
| 136 | } | ||||
| 137 | |||||
| 138 | GlobalVariable oldVariable = createIfNotDefined(oldName); | ||||
| 139 | GlobalVariable variable = (GlobalVariable)globalVariables.get(name); | ||||
| 140 | |||||
| 141 | if (variable != null && oldVariable != variable && variable.isTracing()) { | ||||
| 142 | - throw new RaiseException(runtime, runtime.getRuntimeError(), "can't alias in tracer", false); | ||||
| 143 | + throw new RaiseException(Ruby.getCurrentRuntime(), Ruby.getCurrentRuntime().getRuntimeError(), | ||||
| 144 | + "can't alias in tracer", false); | ||||
| 145 | } | ||||
| 146 | |||||
| 147 | globalVariables.put(name, oldVariable); | ||||
| 148 | @@ -111,16 +107,16 @@ | ||||
| 149 | if (variable != null) { | ||||
| 150 | return variable.getAccessor().getValue(); | ||||
| 151 | } | ||||
| 152 | - runtime.getWarnings().warning(ID.GLOBAL_NOT_INITIALIZED, "global variable `" + name + "' not initialized", name); | ||||
| 153 | - return runtime.getNil(); | ||||
| 154 | + Ruby.getCurrentRuntime().getWarnings().warning(ID.GLOBAL_NOT_INITIALIZED, "global variable `" + name + "' not initialized", name); | ||||
| 155 | + return Ruby.getCurrentRuntime().getNil(); | ||||
| 156 | } | ||||
| 157 | |||||
| 158 | public IRubyObject set(String name, IRubyObject value) { | ||||
| 159 | assert name != null; | ||||
| 160 | assert name.startsWith("$"); | ||||
| 161 | |||||
| 162 | - if (runtime.getSafeLevel() >= 4) { | ||||
| 163 | - throw runtime.newSecurityError("Insecure: can't change global variable value"); | ||||
| 164 | + if (Ruby.getCurrentRuntime().getSafeLevel() >= 4) { | ||||
| 165 | + throw Ruby.getCurrentRuntime().newSecurityError("Insecure: can't change global variable value"); | ||||
| 166 | } | ||||
| 167 | |||||
| 168 | GlobalVariable variable = createIfNotDefined(name); | ||||
| 169 | @@ -165,7 +161,7 @@ | ||||
| 170 | private GlobalVariable createIfNotDefined(String name) { | ||||
| 171 | GlobalVariable variable = (GlobalVariable)globalVariables.get(name); | ||||
| 172 | if (variable == null) { | ||||
| 173 | - variable = GlobalVariable.newUndefined(runtime, name); | ||||
| 174 | + variable = GlobalVariable.newUndefined(Ruby.getCurrentRuntime(), name); | ||||
| 175 | globalVariables.put(name, variable); | ||||
| 176 | } | ||||
| 177 | return variable; | ||||
| 178 | Index: src/org/jruby/internal/runtime/RuntimeVariableAccessor.java | ||||
| 179 | =================================================================== | ||||
| 180 | --- src/org/jruby/internal/runtime/RuntimeVariableAccessor.java (revision 0) | ||||
| 181 | +++ src/org/jruby/internal/runtime/RuntimeVariableAccessor.java (revision 0) | ||||
| 182 | @@ -0,0 +1,32 @@ | ||||
| 183 | +package org.jruby.internal.runtime; | ||||
| 184 | + | ||||
| 185 | +import org.jruby.runtime.IAccessor; | ||||
| 186 | +import org.jruby.runtime.builtin.IRubyObject; | ||||
| 187 | +import org.jruby.Ruby; | ||||
| 188 | + | ||||
| 189 | +/** | ||||
| 190 | + * @author Fabio Kung | ||||
| 191 | + */ | ||||
| 192 | +public class RuntimeVariableAccessor implements IAccessor { | ||||
| 193 | + private final String name; | ||||
| 194 | + | ||||
| 195 | + public RuntimeVariableAccessor(String name) { | ||||
| 196 | + this.name = name; | ||||
| 197 | + } | ||||
| 198 | + | ||||
| 199 | + public RuntimeVariableAccessor(String name, IRubyObject value) { | ||||
| 200 | + this.name = name; | ||||
| 201 | + setValue(value); | ||||
| 202 | + } | ||||
| 203 | + | ||||
| 204 | + public IRubyObject getValue() { | ||||
| 205 | + Ruby runtime = Ruby.getCurrentRuntime(); | ||||
| 206 | + return runtime.getRuntimeVariable(this.name); | ||||
| 207 | + } | ||||
| 208 | + | ||||
| 209 | + public IRubyObject setValue(IRubyObject newValue) { | ||||
| 210 | + Ruby runtime = Ruby.getCurrentRuntime(); | ||||
| 211 | + runtime.setRuntimeVariable(this.name, newValue); | ||||
| 212 | + return newValue; | ||||
| 213 | + } | ||||
| 214 | +} | ||||
| 215 | Index: src/org/jruby/RubyArgsFile.java | ||||
| 216 | =================================================================== | ||||
| 217 | --- src/org/jruby/RubyArgsFile.java (revision 8091) | ||||
| 218 | +++ src/org/jruby/RubyArgsFile.java (working copy) | ||||
| 219 | @@ -39,6 +39,7 @@ | ||||
| 220 | import org.jruby.runtime.ThreadContext; | ||||
| 221 | import org.jruby.runtime.builtin.IRubyObject; | ||||
| 222 | import org.jruby.util.ByteList; | ||||
| 223 | +import org.jruby.internal.runtime.RuntimeVariableAccessor; | ||||
| 224 | |||||
| 225 | public class RubyArgsFile { | ||||
| 226 | private static final class ArgsFileData { | ||||
| 227 | @@ -106,12 +107,13 @@ | ||||
| 228 | |||||
| 229 | runtime.getEnumerable().extend_object(argsFile); | ||||
| 230 | |||||
| 231 | - runtime.defineReadonlyVariable("$<", argsFile); | ||||
| 232 | + runtime.getGlobalVariables().defineReadonly("$<", new RuntimeVariableAccessor("$<", argsFile)); | ||||
| 233 | runtime.defineGlobalConstant("ARGF", argsFile); | ||||
| 234 | |||||
| 235 | RubyClass argfClass = argsFile.getMetaClass(); | ||||
| 236 | argfClass.defineAnnotatedMethods(RubyArgsFile.class); | ||||
| 237 | - runtime.defineReadonlyVariable("$FILENAME", runtime.newString("-")); | ||||
| 238 | + runtime.getGlobalVariables().defineReadonly("$FILENAME", | ||||
| 239 | + new RuntimeVariableAccessor("$FILENAME", runtime.newString("-"))); | ||||
| 240 | } | ||||
| 241 | |||||
| 242 | @JRubyMethod(name = {"fileno", "to_i"}) | ||||
| 243 | Index: src/org/jruby/RubyFile.java | ||||
| 244 | =================================================================== | ||||
| 245 | --- src/org/jruby/RubyFile.java (revision 8091) | ||||
| 246 | +++ src/org/jruby/RubyFile.java (working copy) | ||||
| 247 | @@ -165,7 +165,7 @@ | ||||
| 248 | super(runtime, runtime.getFile()); | ||||
| 249 | this.path = path; | ||||
| 250 | try { | ||||
| 251 | - this.openFile.setMainStream(new ChannelStream(runtime, new ChannelDescriptor(Channels.newChannel(in), getNewFileno(), new FileDescriptor()))); | ||||
| 252 | + this.openFile.setMainStream(new ChannelStream(new ChannelDescriptor(Channels.newChannel(in), getNewFileno(), new FileDescriptor()))); | ||||
| 253 | } catch (InvalidValueException ex) { | ||||
| 254 | throw runtime.newErrnoEINVALError(); | ||||
| 255 | } | ||||
| 256 | Index: src/org/jruby/Ruby.java | ||||
| 257 | =================================================================== | ||||
| 258 | --- src/org/jruby/Ruby.java (revision 8091) | ||||
| 259 | +++ src/org/jruby/Ruby.java (working copy) | ||||
| 260 | @@ -110,6 +110,7 @@ | ||||
| 261 | import org.jruby.runtime.ObjectSpace; | ||||
| 262 | import org.jruby.runtime.RubyEvent; | ||||
| 263 | import org.jruby.runtime.ThreadContext; | ||||
| 264 | +import org.jruby.runtime.GlobalVariableAcessor; | ||||
| 265 | import org.jruby.runtime.builtin.IRubyObject; | ||||
| 266 | import org.jruby.runtime.encoding.EncodingService; | ||||
| 267 | import org.jruby.runtime.load.Library; | ||||
| 268 | @@ -122,6 +123,7 @@ | ||||
| 269 | import org.jruby.util.JRubyClassLoader; | ||||
| 270 | import org.jruby.util.JavaNameMangler; | ||||
| 271 | import org.jruby.util.KCode; | ||||
| 272 | +import org.jruby.util.RuntimeContainer; | ||||
| 273 | import org.jruby.util.SafePropertyAccessor; | ||||
| 274 | import org.jruby.util.collections.WeakHashSet; | ||||
| 275 | import org.jruby.util.io.ChannelDescriptor; | ||||
| 276 | @@ -136,7 +138,7 @@ | ||||
| 277 | * multiple instances of each class. This means that in multi-runtime mode | ||||
| 278 | * (or really, multi-VM mode, where each JRuby instance is a ruby "VM"), objects | ||||
| 279 | * generally can't be transported across runtimes without marshaling. | ||||
| 280 | - * | ||||
| 281 | + * | ||||
| 282 | * This class roots everything that makes the JRuby runtime function, and | ||||
| 283 | * provides a number of utility methods for constructing global types and | ||||
| 284 | * accessing global runtime structures. | ||||
| 285 | @@ -183,16 +185,27 @@ | ||||
| 286 | config.setError(err); | ||||
| 287 | return newInstance(config); | ||||
| 288 | } | ||||
| 289 | - | ||||
| 290 | + | ||||
| 291 | + public static Ruby getCurrentRuntime() { | ||||
| 292 | + JRubyClassLoader loader = (JRubyClassLoader) Thread.currentThread().getContextClassLoader(); | ||||
| 293 | + while (!(loader instanceof RuntimeContainer)) { | ||||
| 294 | + loader = (JRubyClassLoader) loader.getParent(); | ||||
| 295 | + } | ||||
| 296 | + return ((RuntimeContainer) loader).getRuntime(); | ||||
| 297 | + } | ||||
| 298 | + | ||||
| 299 | /** | ||||
| 300 | * Create and initialize a new JRuby runtime. The properties of the | ||||
| 301 | * specified RubyInstanceConfig will be used to determine various JRuby | ||||
| 302 | * runtime characteristics. | ||||
| 303 | - * | ||||
| 304 | + * | ||||
| 305 | * @param config The configuration to use for the new instance | ||||
| 306 | * @see org.jruby.RubyInstanceConfig | ||||
| 307 | */ | ||||
| 308 | private Ruby(RubyInstanceConfig config) { | ||||
| 309 | + Thread currentThread = Thread.currentThread(); | ||||
| 310 | + currentThread.setContextClassLoader(new RuntimeContainer(currentThread.getContextClassLoader(), this)); | ||||
| 311 | + | ||||
| 312 | this.config = config; | ||||
| 313 | this.threadService = new ThreadService(this); | ||||
| 314 | if(config.isSamplingEnabled()) { | ||||
| 315 | @@ -209,18 +222,18 @@ | ||||
| 316 | this.beanManager = new BeanManager(this, config.isManagementEnabled()); | ||||
| 317 | this.jitCompiler = new JITCompiler(this); | ||||
| 318 | this.parserStats = new ParserStats(this); | ||||
| 319 | - | ||||
| 320 | + | ||||
| 321 | this.beanManager.register(new Config(this)); | ||||
| 322 | this.beanManager.register(parserStats); | ||||
| 323 | this.beanManager.register(new ClassCache(this)); | ||||
| 324 | } | ||||
| 325 | - | ||||
| 326 | + | ||||
| 327 | /** | ||||
| 328 | * Evaluates a script under the current scope (perhaps the top-level | ||||
| 329 | * scope) and returns the result (generally the last value calculated). | ||||
| 330 | * This version goes straight into the interpreter, bypassing compilation | ||||
| 331 | * and runtime preparation typical to normal script runs. | ||||
| 332 | - * | ||||
| 333 | + * | ||||
| 334 | * @param script The scriptlet to run | ||||
| 335 | * @returns The result of the eval | ||||
| 336 | */ | ||||
| 337 | @@ -229,7 +242,7 @@ | ||||
| 338 | DynamicScope currentScope = context.getCurrentScope(); | ||||
| 339 | ManyVarsDynamicScope newScope = new ManyVarsDynamicScope(new EvalStaticScope(currentScope.getStaticScope()), currentScope); | ||||
| 340 | Node node = parseEval(script, "<script>", newScope, 0); | ||||
| 341 | - | ||||
| 342 | + | ||||
| 343 | try { | ||||
| 344 | context.preEvalScriptlet(newScope); | ||||
| 345 | return node.interpret(this, context, context.getFrameSelf(), Block.NULL_BLOCK); | ||||
| 346 | @@ -243,20 +256,20 @@ | ||||
| 347 | context.postEvalScriptlet(); | ||||
| 348 | } | ||||
| 349 | } | ||||
| 350 | - | ||||
| 351 | + | ||||
| 352 | /** | ||||
| 353 | - * Parse and execute the specified script | ||||
| 354 | + * Parse and execute the specified script | ||||
| 355 | * This differs from the other methods in that it accepts a string-based script and | ||||
| 356 | * parses and runs it as though it were loaded at a command-line. This is the preferred | ||||
| 357 | * way to start up a new script when calling directly into the Ruby object (which is | ||||
| 358 | * generally *dis*couraged. | ||||
| 359 | - * | ||||
| 360 | + * | ||||
| 361 | * @param script The contents of the script to run as a normal, root script | ||||
| 362 | * @return The last value of the script | ||||
| 363 | */ | ||||
| 364 | public IRubyObject executeScript(String script, String filename) { | ||||
| 365 | byte[] bytes; | ||||
| 366 | - | ||||
| 367 | + | ||||
| 368 | try { | ||||
| 369 | bytes = script.getBytes(KCode.NONE.getKCode()); | ||||
| 370 | } catch (UnsupportedEncodingException e) { | ||||
| 371 | @@ -265,7 +278,7 @@ | ||||
| 372 | |||||
| 373 | Node node = parseInline(new ByteArrayInputStream(bytes), filename, null); | ||||
| 374 | ThreadContext context = getCurrentContext(); | ||||
| 375 | - | ||||
| 376 | + | ||||
| 377 | String oldFile = context.getFile(); | ||||
| 378 | int oldLine = context.getLine(); | ||||
| 379 | try { | ||||
| 380 | @@ -277,22 +290,22 @@ | ||||
| 381 | context.setLine(oldLine); | ||||
| 382 | } | ||||
| 383 | } | ||||
| 384 | - | ||||
| 385 | + | ||||
| 386 | /** | ||||
| 387 | * Run the script contained in the specified input stream, using the | ||||
| 388 | * specified filename as the name of the script being executed. The stream | ||||
| 389 | * will be read fully before being parsed and executed. The given filename | ||||
| 390 | * will be used for the ruby $PROGRAM_NAME and $0 global variables in this | ||||
| 391 | * runtime. | ||||
| 392 | - * | ||||
| 393 | + * | ||||
| 394 | * This method is intended to be called once per runtime, generally from | ||||
| 395 | * Main or from main-like top-level entry points. | ||||
| 396 | - * | ||||
| 397 | + * | ||||
| 398 | * As part of executing the script loaded from the input stream, various | ||||
| 399 | * RubyInstanceConfig properties will be used to determine whether to | ||||
| 400 | * compile the script before execution or run with various wrappers (for | ||||
| 401 | * looping, printing, and so on, see jruby -help). | ||||
| 402 | - * | ||||
| 403 | + * | ||||
| 404 | * @param inputStream The InputStream from which to read the script contents | ||||
| 405 | * @param filename The filename to use when parsing, and for $PROGRAM_NAME | ||||
| 406 | * and $0 ruby global variables. | ||||
| 407 | @@ -314,7 +327,7 @@ | ||||
| 408 | getGlobalVariables().set("$" + entry.getKey().toString(), varvalue); | ||||
| 409 | } | ||||
| 410 | |||||
| 411 | - | ||||
| 412 | + | ||||
| 413 | if(config.isYARVEnabled()) { | ||||
| 414 | if (config.isShowBytecode()) System.err.print("error: bytecode printing only works with JVM bytecode"); | ||||
| 415 | new YARVCompiledRunner(this, inputStream, filename).run(); | ||||
| 416 | @@ -350,7 +363,7 @@ | ||||
| 417 | * is used to verify that the script syntax is valid, for jruby -c. The | ||||
| 418 | * current scope (generally the top-level scope) is used as the parent | ||||
| 419 | * scope for parsing. | ||||
| 420 | - * | ||||
| 421 | + * | ||||
| 422 | * @param inputStream The input stream from which to read the script | ||||
| 423 | * @param filename The filename to use for parsing | ||||
| 424 | * @returns The root node of the parsed script | ||||
| 425 | @@ -362,12 +375,12 @@ | ||||
| 426 | return parseFile(inputStream, filename, getCurrentContext().getCurrentScope()); | ||||
| 427 | } | ||||
| 428 | } | ||||
| 429 | - | ||||
| 430 | + | ||||
| 431 | /** | ||||
| 432 | * Run the given script with a "while gets; end" loop wrapped around it. | ||||
| 433 | * This is primarily used for the -n command-line flag, to allow writing | ||||
| 434 | * a short script that processes input lines using the specified code. | ||||
| 435 | - * | ||||
| 436 | + * | ||||
| 437 | * @param scriptNode The root node of the script to execute | ||||
| 438 | * @param printing Whether $_ should be printed after each loop (as in the | ||||
| 439 | * -p command-line flag) | ||||
| 440 | @@ -380,7 +393,7 @@ | ||||
| 441 | */ | ||||
| 442 | public IRubyObject runWithGetsLoop(Node scriptNode, boolean printing, boolean processLineEnds, boolean split, boolean yarvCompile) { | ||||
| 443 | ThreadContext context = getCurrentContext(); | ||||
| 444 | - | ||||
| 445 | + | ||||
| 446 | Script script = null; | ||||
| 447 | YARVCompiledRunner runner = null; | ||||
| 448 | boolean compile = getInstanceConfig().getCompileMode().shouldPrecompileCLI(); | ||||
| 449 | @@ -393,22 +406,22 @@ | ||||
| 450 | } else if (yarvCompile) { | ||||
| 451 | runner = tryCompileYarv(scriptNode); | ||||
| 452 | } | ||||
| 453 | - | ||||
| 454 | + | ||||
| 455 | if (processLineEnds) { | ||||
| 456 | getGlobalVariables().set("$\\", getGlobalVariables().get("$/")); | ||||
| 457 | } | ||||
| 458 | - | ||||
| 459 | + | ||||
| 460 | while (RubyKernel.gets(context, getTopSelf(), IRubyObject.NULL_ARRAY).isTrue()) { | ||||
| 461 | loop: while (true) { // Used for the 'redo' command | ||||
| 462 | try { | ||||
| 463 | if (processLineEnds) { | ||||
| 464 | getGlobalVariables().get("$_").callMethod(context, "chop!"); | ||||
| 465 | } | ||||
| 466 | - | ||||
| 467 | + | ||||
| 468 | if (split) { | ||||
| 469 | getGlobalVariables().set("$F", getGlobalVariables().get("$_").callMethod(context, "split")); | ||||
| 470 | } | ||||
| 471 | - | ||||
| 472 | + | ||||
| 473 | if (script != null) { | ||||
| 474 | runScript(script); | ||||
| 475 | } else if (runner != null) { | ||||
| 476 | @@ -416,7 +429,7 @@ | ||||
| 477 | } else { | ||||
| 478 | runInterpreter(scriptNode); | ||||
| 479 | } | ||||
| 480 | - | ||||
| 481 | + | ||||
| 482 | if (printing) RubyKernel.print(context, getKernel(), new IRubyObject[] {getGlobalVariables().get("$_")}); | ||||
| 483 | break loop; | ||||
| 484 | } catch (JumpException.RedoJump rj) { | ||||
| 485 | @@ -430,14 +443,14 @@ | ||||
| 486 | } | ||||
| 487 | } | ||||
| 488 | } | ||||
| 489 | - | ||||
| 490 | + | ||||
| 491 | return getNil(); | ||||
| 492 | } | ||||
| 493 | - | ||||
| 494 | + | ||||
| 495 | /** | ||||
| 496 | * Run the specified script without any of the loop-processing wrapper | ||||
| 497 | * code. | ||||
| 498 | - * | ||||
| 499 | + * | ||||
| 500 | * @param scriptNode The root node of the script to be executed | ||||
| 501 | * @param yarvCompile Whether to compile the script to YARV (Ruby 1.9) | ||||
| 502 | * bytecode before execution | ||||
| 503 | @@ -456,7 +469,7 @@ | ||||
| 504 | return getNil(); | ||||
| 505 | } | ||||
| 506 | } | ||||
| 507 | - | ||||
| 508 | + | ||||
| 509 | if (script != null) { | ||||
| 510 | if (config.isShowBytecode()) { | ||||
| 511 | return nilObject; | ||||
| 512 | @@ -470,11 +483,11 @@ | ||||
| 513 | return runInterpreter(scriptNode); | ||||
| 514 | } | ||||
| 515 | } | ||||
| 516 | - | ||||
| 517 | + | ||||
| 518 | private Script tryCompile(Node node) { | ||||
| 519 | return tryCompile(node, new JRubyClassLoader(getJRubyClassLoader())); | ||||
| 520 | } | ||||
| 521 | - | ||||
| 522 | + | ||||
| 523 | private Script tryCompile(Node node, JRubyClassLoader classLoader) { | ||||
| 524 | Script script = null; | ||||
| 525 | try { | ||||
| 526 | @@ -533,10 +546,10 @@ | ||||
| 527 | System.err.println("Error, could not compile; pass -d or -J-Djruby.jit.logging.verbose=true for more details"); | ||||
| 528 | } | ||||
| 529 | } | ||||
| 530 | - | ||||
| 531 | + | ||||
| 532 | return script; | ||||
| 533 | } | ||||
| 534 | - | ||||
| 535 | + | ||||
| 536 | private YARVCompiledRunner tryCompileYarv(Node node) { | ||||
| 537 | try { | ||||
| 538 | StandardYARVCompiler compiler = new StandardYARVCompiler(this); | ||||
| 539 | @@ -553,17 +566,17 @@ | ||||
| 540 | return null; | ||||
| 541 | } | ||||
| 542 | } | ||||
| 543 | - | ||||
| 544 | + | ||||
| 545 | private IRubyObject runScript(Script script) { | ||||
| 546 | ThreadContext context = getCurrentContext(); | ||||
| 547 | - | ||||
| 548 | + | ||||
| 549 | try { | ||||
| 550 | return script.load(context, context.getFrameSelf(), IRubyObject.NULL_ARRAY, Block.NULL_BLOCK); | ||||
| 551 | } catch (JumpException.ReturnJump rj) { | ||||
| 552 | return (IRubyObject) rj.getValue(); | ||||
| 553 | } | ||||
| 554 | } | ||||
| 555 | - | ||||
| 556 | + | ||||
| 557 | private IRubyObject runYarv(YARVCompiledRunner runner) { | ||||
| 558 | try { | ||||
| 559 | return runner.run(); | ||||
| 560 | @@ -571,12 +584,12 @@ | ||||
| 561 | return (IRubyObject) rj.getValue(); | ||||
| 562 | } | ||||
| 563 | } | ||||
| 564 | - | ||||
| 565 | + | ||||
| 566 | private IRubyObject runInterpreter(Node scriptNode) { | ||||
| 567 | ThreadContext context = getCurrentContext(); | ||||
| 568 | - | ||||
| 569 | + | ||||
| 570 | assert scriptNode != null : "scriptNode is not null"; | ||||
| 571 | - | ||||
| 572 | + | ||||
| 573 | try { | ||||
| 574 | return scriptNode.interpret(this, context, getTopSelf(), Block.NULL_BLOCK); | ||||
| 575 | } catch (JumpException.ReturnJump rj) { | ||||
| 576 | @@ -587,11 +600,11 @@ | ||||
| 577 | public Parser getParser() { | ||||
| 578 | return parser; | ||||
| 579 | } | ||||
| 580 | - | ||||
| 581 | + | ||||
| 582 | public BeanManager getBeanManager() { | ||||
| 583 | return beanManager; | ||||
| 584 | } | ||||
| 585 | - | ||||
| 586 | + | ||||
| 587 | public JITCompiler getJITCompiler() { | ||||
| 588 | return jitCompiler; | ||||
| 589 | } | ||||
| 590 | @@ -602,16 +615,16 @@ | ||||
| 591 | public static Ruby getDefaultInstance() { | ||||
| 592 | return newInstance(); | ||||
| 593 | } | ||||
| 594 | - | ||||
| 595 | + | ||||
| 596 | @Deprecated | ||||
| 597 | public static Ruby getCurrentInstance() { | ||||
| 598 | return null; | ||||
| 599 | } | ||||
| 600 | - | ||||
| 601 | + | ||||
| 602 | @Deprecated | ||||
| 603 | public static void setCurrentInstance(Ruby runtime) { | ||||
| 604 | } | ||||
| 605 | - | ||||
| 606 | + | ||||
| 607 | public int allocSymbolId() { | ||||
| 608 | return symbolLastId.incrementAndGet(); | ||||
| 609 | } | ||||
| 610 | @@ -621,7 +634,7 @@ | ||||
| 611 | |||||
| 612 | /** | ||||
| 613 | * Retrieve the module with the given name from the Object namespace. | ||||
| 614 | - * | ||||
| 615 | + * | ||||
| 616 | * @param name The name of the module | ||||
| 617 | * @return The module or null if not found | ||||
| 618 | */ | ||||
| 619 | @@ -633,7 +646,7 @@ | ||||
| 620 | * Retrieve the module with the given name from the Object namespace. The | ||||
| 621 | * module name must be an interned string, but this method will be faster | ||||
| 622 | * than the non-interned version. | ||||
| 623 | - * | ||||
| 624 | + * | ||||
| 625 | * @param internedName The name of the module; <em>must</em> be an interned String | ||||
| 626 | * @return The module or null if not found | ||||
| 627 | */ | ||||
| 628 | @@ -641,7 +654,7 @@ | ||||
| 629 | return (RubyModule) objectClass.fastGetConstantAt(internedName); | ||||
| 630 | } | ||||
| 631 | |||||
| 632 | - /** | ||||
| 633 | + /** | ||||
| 634 | * Retrieve the class with the given name from the Object namespace. | ||||
| 635 | * | ||||
| 636 | * @param name The name of the class | ||||
| 637 | @@ -655,7 +668,7 @@ | ||||
| 638 | * Retrieve the class with the given name from the Object namespace. The | ||||
| 639 | * module name must be an interned string, but this method will be faster | ||||
| 640 | * than the non-interned version. | ||||
| 641 | - * | ||||
| 642 | + * | ||||
| 643 | * @param internedName the name of the class; <em>must</em> be an interned String! | ||||
| 644 | * @return | ||||
| 645 | */ | ||||
| 646 | @@ -663,7 +676,7 @@ | ||||
| 647 | return objectClass.fastGetClass(internedName); | ||||
| 648 | } | ||||
| 649 | |||||
| 650 | - /** | ||||
| 651 | + /** | ||||
| 652 | * Define a new class under the Object namespace. Roughly equivalent to | ||||
| 653 | * rb_define_class in MRI. | ||||
| 654 | * | ||||
| 655 | @@ -677,7 +690,7 @@ | ||||
| 656 | return defineClassUnder(name, superClass, allocator, objectClass); | ||||
| 657 | } | ||||
| 658 | |||||
| 659 | - /** | ||||
| 660 | + /** | ||||
| 661 | * A variation of defineClass that allows passing in an array of subplementary | ||||
| 662 | * call sites for improving dynamic invocation performance. | ||||
| 663 | * | ||||
| 664 | @@ -694,7 +707,7 @@ | ||||
| 665 | /** | ||||
| 666 | * Define a new class with the given name under the given module or class | ||||
| 667 | * namespace. Roughly equivalent to rb_define_class_under in MRI. | ||||
| 668 | - * | ||||
| 669 | + * | ||||
| 670 | * If the name specified is already bound, its value will be returned if: | ||||
| 671 | * * It is a class | ||||
| 672 | * * No new superclass is being defined | ||||
| 673 | @@ -738,23 +751,23 @@ | ||||
| 674 | } | ||||
| 675 | return klazz; | ||||
| 676 | } | ||||
| 677 | - | ||||
| 678 | + | ||||
| 679 | boolean parentIsObject = parent == objectClass; | ||||
| 680 | |||||
| 681 | if (superClass == null) { | ||||
| 682 | - String className = parentIsObject ? name : parent.getName() + "::" + name; | ||||
| 683 | + String className = parentIsObject ? name : parent.getName() + "::" + name; | ||||
| 684 | warnings.warn(ID.NO_SUPER_CLASS, "no super class for `" + className + "', Object assumed", className); | ||||
| 685 | - | ||||
| 686 | + | ||||
| 687 | superClass = objectClass; | ||||
| 688 | } | ||||
| 689 | |||||
| 690 | return RubyClass.newClass(this, superClass, name, allocator, parent, !parentIsObject, callSites); | ||||
| 691 | } | ||||
| 692 | |||||
| 693 | - /** | ||||
| 694 | + /** | ||||
| 695 | * Define a new module under the Object namespace. Roughly equivalent to | ||||
| 696 | * rb_define_module in MRI. | ||||
| 697 | - * | ||||
| 698 | + * | ||||
| 699 | * @param name The name of the new module | ||||
| 700 | * @returns The new module | ||||
| 701 | */ | ||||
| 702 | @@ -765,7 +778,7 @@ | ||||
| 703 | /** | ||||
| 704 | * Define a new module with the given name under the given module or | ||||
| 705 | * class namespace. Roughly equivalent to rb_define_module_under in MRI. | ||||
| 706 | - * | ||||
| 707 | + * | ||||
| 708 | * @param name The name of the new module | ||||
| 709 | * @param parent The class or module namespace under which to define the | ||||
| 710 | * module | ||||
| 711 | @@ -773,12 +786,12 @@ | ||||
| 712 | */ | ||||
| 713 | public RubyModule defineModuleUnder(String name, RubyModule parent) { | ||||
| 714 | IRubyObject moduleObj = parent.getConstantAt(name); | ||||
| 715 | - | ||||
| 716 | + | ||||
| 717 | boolean parentIsObject = parent == objectClass; | ||||
| 718 | |||||
| 719 | if (moduleObj != null ) { | ||||
| 720 | if (moduleObj.isModule()) return (RubyModule)moduleObj; | ||||
| 721 | - | ||||
| 722 | + | ||||
| 723 | if (parentIsObject) { | ||||
| 724 | throw newTypeError(moduleObj.getMetaClass().getName() + " is not a module"); | ||||
| 725 | } else { | ||||
| 726 | @@ -792,7 +805,7 @@ | ||||
| 727 | /** | ||||
| 728 | * From Object, retrieve the named module. If it doesn't exist a | ||||
| 729 | * new module is created. | ||||
| 730 | - * | ||||
| 731 | + * | ||||
| 732 | * @param name The name of the module | ||||
| 733 | * @returns The existing or new module | ||||
| 734 | */ | ||||
| 735 | @@ -810,9 +823,9 @@ | ||||
| 736 | } | ||||
| 737 | |||||
| 738 | |||||
| 739 | - /** | ||||
| 740 | + /** | ||||
| 741 | * Retrieve the current safe level. | ||||
| 742 | - * | ||||
| 743 | + * | ||||
| 744 | * @see org.jruby.Ruby#setSaveLevel | ||||
| 745 | */ | ||||
| 746 | public int getSafeLevel() { | ||||
| 747 | @@ -820,15 +833,15 @@ | ||||
| 748 | } | ||||
| 749 | |||||
| 750 | |||||
| 751 | - /** | ||||
| 752 | + /** | ||||
| 753 | * Set the current safe level: | ||||
| 754 | - * | ||||
| 755 | + * | ||||
| 756 | * 0 - strings from streams/environment/ARGV are tainted (default) | ||||
| 757 | * 1 - no dangerous operation by tainted value | ||||
| 758 | * 2 - process/file operations prohibited | ||||
| 759 | * 3 - all generated objects are tainted | ||||
| 760 | * 4 - no global (non-tainted) variable modification/no direct output | ||||
| 761 | - * | ||||
| 762 | + * | ||||
| 763 | * The safe level is set using $SAFE in Ruby code. It is not particularly | ||||
| 764 | * well supported in JRuby. | ||||
| 765 | */ | ||||
| 766 | @@ -877,7 +890,7 @@ | ||||
| 767 | public boolean isClassDefined(String name) { | ||||
| 768 | return getModule(name) != null; | ||||
| 769 | } | ||||
| 770 | - | ||||
| 771 | + | ||||
| 772 | /** | ||||
| 773 | * A ThreadFactory for when we're using pooled threads; we want to create | ||||
| 774 | * the threads with daemon = true so they don't keep us from shutting down. | ||||
| 775 | @@ -886,12 +899,12 @@ | ||||
| 776 | public Thread newThread(Runnable runnable) { | ||||
| 777 | Thread thread = new Thread(runnable); | ||||
| 778 | thread.setDaemon(true); | ||||
| 779 | - | ||||
| 780 | + | ||||
| 781 | return thread; | ||||
| 782 | } | ||||
| 783 | } | ||||
| 784 | |||||
| 785 | - /** | ||||
| 786 | + /** | ||||
| 787 | * This method is called immediately after constructing the Ruby instance. | ||||
| 788 | * The main thread is prepared for execution, all core classes and libraries | ||||
| 789 | * are initialized, and any libraries required on the command line are | ||||
| 790 | @@ -902,12 +915,12 @@ | ||||
| 791 | ThreadContext tc = getCurrentContext(); | ||||
| 792 | |||||
| 793 | safeLevel = config.getSafeLevel(); | ||||
| 794 | - | ||||
| 795 | + | ||||
| 796 | // Construct key services | ||||
| 797 | loadService = config.createLoadService(this); | ||||
| 798 | posix = POSIXFactory.getPOSIX(new JRubyPOSIXHandler(this), RubyInstanceConfig.nativeEnabled); | ||||
| 799 | javaSupport = new JavaSupport(this); | ||||
| 800 | - | ||||
| 801 | + | ||||
| 802 | if (RubyInstanceConfig.POOLING_ENABLED) { | ||||
| 803 | Executors.newCachedThreadPool(); | ||||
| 804 | executor = new ThreadPoolExecutor( | ||||
| 805 | @@ -918,7 +931,7 @@ | ||||
| 806 | new SynchronousQueue<Runnable>(), | ||||
| 807 | new DaemonThreadFactory()); | ||||
| 808 | } | ||||
| 809 | - | ||||
| 810 | + | ||||
| 811 | // initialize the root of the class hierarchy completely | ||||
| 812 | initRoot(); | ||||
| 813 | |||||
| 814 | @@ -927,11 +940,11 @@ | ||||
| 815 | |||||
| 816 | // Initialize all the core classes | ||||
| 817 | bootstrap(); | ||||
| 818 | - | ||||
| 819 | + | ||||
| 820 | // Initialize the "dummy" class used as a marker | ||||
| 821 | dummyClass = new RubyClass(this, classClass); | ||||
| 822 | dummyClass.freeze(tc); | ||||
| 823 | - | ||||
| 824 | + | ||||
| 825 | // Create global constants and variables | ||||
| 826 | RubyGlobal.createGlobals(tc, this); | ||||
| 827 | |||||
| 828 | @@ -940,7 +953,7 @@ | ||||
| 829 | |||||
| 830 | // initialize builtin libraries | ||||
| 831 | initBuiltins(); | ||||
| 832 | - | ||||
| 833 | + | ||||
| 834 | // Require in all libraries specified on command line | ||||
| 835 | for (String scriptName : config.requiredLibraries()) { | ||||
| 836 | RubyKernel.require(getTopSelf(), newString(scriptName), Block.NULL_BLOCK); | ||||
| 837 | @@ -969,8 +982,8 @@ | ||||
| 838 | |||||
| 839 | RubyObject.createObjectClass(this, objectClass); | ||||
| 840 | RubyModule.createModuleClass(this, moduleClass); | ||||
| 841 | - RubyClass.createClassClass(this, classClass); | ||||
| 842 | - | ||||
| 843 | + RubyClass.createClassClass(classClass); | ||||
| 844 | + | ||||
| 845 | // set constants now that they're initialized | ||||
| 846 | objectClass.setConstant("Object", objectClass); | ||||
| 847 | objectClass.setConstant("Class", classClass); | ||||
| 848 | @@ -1144,10 +1157,10 @@ | ||||
| 849 | scriptError = defineClassIfAllowed("ScriptError", exceptionClass); | ||||
| 850 | rangeError = defineClassIfAllowed("RangeError", standardError); | ||||
| 851 | signalException = defineClassIfAllowed("SignalException", exceptionClass); | ||||
| 852 | - | ||||
| 853 | + | ||||
| 854 | if (profile.allowClass("NameError")) { | ||||
| 855 | nameError = RubyNameError.createNameErrorClass(this, standardError); | ||||
| 856 | - nameErrorMessage = RubyNameError.createNameErrorMessageClass(this, nameError); | ||||
| 857 | + nameErrorMessage = RubyNameError.createNameErrorMessageClass(this, nameError); | ||||
| 858 | } | ||||
| 859 | if (profile.allowClass("NoMethodError")) { | ||||
| 860 | noMethodError = RubyNoMethodError.createNoMethodErrorClass(this, nameError); | ||||
| 861 | @@ -1185,14 +1198,14 @@ | ||||
| 862 | |||||
| 863 | if (config.getCompatVersion() == CompatVersion.RUBY1_9) { | ||||
| 864 | if (profile.allowClass("EncodingError")) { | ||||
| 865 | - encodingError = defineClass("EncodingError", standardError, standardError.getAllocator()); | ||||
| 866 | + encodingError = defineClass("EncodingError", standardError, standardError.getAllocator()); | ||||
| 867 | encodingCompatibilityError = defineClassUnder("CompatibilityError", encodingError, encodingError.getAllocator(), encodingClass); | ||||
| 868 | } | ||||
| 869 | } | ||||
| 870 | |||||
| 871 | initErrno(); | ||||
| 872 | } | ||||
| 873 | - | ||||
| 874 | + | ||||
| 875 | private RubyClass defineClassIfAllowed(String name, RubyClass superClass) { | ||||
| 876 | // TODO: should probably apply the null object pattern for a | ||||
| 877 | // non-allowed class, rather than null | ||||
| 878 | @@ -1237,9 +1250,9 @@ | ||||
| 879 | private void initBuiltins() { | ||||
| 880 | addLazyBuiltin("java.rb", "java", "org.jruby.javasupport.Java"); | ||||
| 881 | addLazyBuiltin("jruby.rb", "jruby", "org.jruby.libraries.JRubyLibrary"); | ||||
| 882 | - | ||||
| 883 | + | ||||
| 884 | addLazyBuiltin("minijava.rb", "minijava", "org.jruby.java.MiniJava"); | ||||
| 885 | - | ||||
| 886 | + | ||||
| 887 | addLazyBuiltin("jruby/ext.rb", "jruby/ext", "org.jruby.RubyJRuby$ExtLibrary"); | ||||
| 888 | addLazyBuiltin("jruby/core_ext.rb", "jruby/ext", "org.jruby.RubyJRuby$CoreExtLibrary"); | ||||
| 889 | addLazyBuiltin("jruby/type.rb", "jruby/type", "org.jruby.RubyJRuby$TypeLibrary"); | ||||
| 890 | @@ -1270,22 +1283,22 @@ | ||||
| 891 | if(RubyInstanceConfig.NATIVE_NET_PROTOCOL) { | ||||
| 892 | addLazyBuiltin("net/protocol.rb", "net/protocol", "org.jruby.libraries.NetProtocolBufferedIOLibrary"); | ||||
| 893 | } | ||||
| 894 | - | ||||
| 895 | + | ||||
| 896 | if (config.getCompatVersion() == CompatVersion.RUBY1_9) { | ||||
| 897 | addLazyBuiltin("fiber.so", "fiber", "org.jruby.libraries.FiberLibrary"); | ||||
| 898 | } | ||||
| 899 | - | ||||
| 900 | + | ||||
| 901 | addBuiltinIfAllowed("openssl.so", new Library() { | ||||
| 902 | public void load(Ruby runtime, boolean wrap) throws IOException { | ||||
| 903 | runtime.getLoadService().require("jruby/openssl/stub"); | ||||
| 904 | } | ||||
| 905 | }); | ||||
| 906 | - | ||||
| 907 | + | ||||
| 908 | String[] builtins = {"fcntl", "yaml", "yaml/syck", "jsignal" }; | ||||
| 909 | for (String library : builtins) { | ||||
| 910 | addBuiltinIfAllowed(library + ".rb", new BuiltinScript(library)); | ||||
| 911 | } | ||||
| 912 | - | ||||
| 913 | + | ||||
| 914 | RubyKernel.autoload(topSelf, newSymbol("Java"), newString("java")); | ||||
| 915 | |||||
| 916 | if (config.getCompatVersion() == CompatVersion.RUBY1_9) { | ||||
| 917 | @@ -1334,11 +1347,11 @@ | ||||
| 918 | public String getCurrentDirectory() { | ||||
| 919 | return currentDirectory; | ||||
| 920 | } | ||||
| 921 | - | ||||
| 922 | + | ||||
| 923 | public RubyModule getEtc() { | ||||
| 924 | return etcModule; | ||||
| 925 | } | ||||
| 926 | - | ||||
| 927 | + | ||||
| 928 | public void setEtc(RubyModule etcModule) { | ||||
| 929 | this.etcModule = etcModule; | ||||
| 930 | } | ||||
| 931 | @@ -1354,14 +1367,14 @@ | ||||
| 932 | public RubyClass getClassClass() { | ||||
| 933 | return classClass; | ||||
| 934 | } | ||||
| 935 | - | ||||
| 936 | + | ||||
| 937 | public RubyModule getKernel() { | ||||
| 938 | return kernelModule; | ||||
| 939 | } | ||||
| 940 | void setKernel(RubyModule kernelModule) { | ||||
| 941 | this.kernelModule = kernelModule; | ||||
| 942 | } | ||||
| 943 | - | ||||
| 944 | + | ||||
| 945 | public RubyClass getDummy() { | ||||
| 946 | return dummyClass; | ||||
| 947 | } | ||||
| 948 | @@ -1371,14 +1384,14 @@ | ||||
| 949 | } | ||||
| 950 | void setComparable(RubyModule comparableModule) { | ||||
| 951 | this.comparableModule = comparableModule; | ||||
| 952 | - } | ||||
| 953 | + } | ||||
| 954 | |||||
| 955 | public RubyClass getNumeric() { | ||||
| 956 | return numericClass; | ||||
| 957 | } | ||||
| 958 | void setNumeric(RubyClass numericClass) { | ||||
| 959 | this.numericClass = numericClass; | ||||
| 960 | - } | ||||
| 961 | + } | ||||
| 962 | |||||
| 963 | public RubyClass getFloat() { | ||||
| 964 | return floatClass; | ||||
| 965 | @@ -1386,14 +1399,14 @@ | ||||
| 966 | void setFloat(RubyClass floatClass) { | ||||
| 967 | this.floatClass = floatClass; | ||||
| 968 | } | ||||
| 969 | - | ||||
| 970 | + | ||||
| 971 | public RubyClass getInteger() { | ||||
| 972 | return integerClass; | ||||
| 973 | } | ||||
| 974 | void setInteger(RubyClass integerClass) { | ||||
| 975 | this.integerClass = integerClass; | ||||
| 976 | - } | ||||
| 977 | - | ||||
| 978 | + } | ||||
| 979 | + | ||||
| 980 | public RubyClass getFixnum() { | ||||
| 981 | return fixnumClass; | ||||
| 982 | } | ||||
| 983 | @@ -1452,7 +1465,7 @@ | ||||
| 984 | |||||
| 985 | public RubyClass getArray() { | ||||
| 986 | return arrayClass; | ||||
| 987 | - } | ||||
| 988 | + } | ||||
| 989 | void setArray(RubyClass arrayClass) { | ||||
| 990 | this.arrayClass = arrayClass; | ||||
| 991 | } | ||||
| 992 | @@ -1532,77 +1545,77 @@ | ||||
| 993 | } | ||||
| 994 | void setMethod(RubyClass methodClass) { | ||||
| 995 | this.methodClass = methodClass; | ||||
| 996 | - } | ||||
| 997 | + } | ||||
| 998 | |||||
| 999 | public RubyClass getUnboundMethod() { | ||||
| 1000 | return unboundMethodClass; | ||||
| 1001 | } | ||||
| 1002 | void setUnboundMethod(RubyClass unboundMethodClass) { | ||||
| 1003 | this.unboundMethodClass = unboundMethodClass; | ||||
| 1004 | - } | ||||
| 1005 | + } | ||||
| 1006 | |||||
| 1007 | public RubyClass getMatchData() { | ||||
| 1008 | return matchDataClass; | ||||
| 1009 | } | ||||
| 1010 | void setMatchData(RubyClass matchDataClass) { | ||||
| 1011 | this.matchDataClass = matchDataClass; | ||||
| 1012 | - } | ||||
| 1013 | + } | ||||
| 1014 | |||||
| 1015 | public RubyClass getRegexp() { | ||||
| 1016 | return regexpClass; | ||||
| 1017 | } | ||||
| 1018 | void setRegexp(RubyClass regexpClass) { | ||||
| 1019 | this.regexpClass = regexpClass; | ||||
| 1020 | - } | ||||
| 1021 | + } | ||||
| 1022 | |||||
| 1023 | public RubyClass getTime() { | ||||
| 1024 | return timeClass; | ||||
| 1025 | } | ||||
| 1026 | void setTime(RubyClass timeClass) { | ||||
| 1027 | this.timeClass = timeClass; | ||||
| 1028 | - } | ||||
| 1029 | + } | ||||
| 1030 | |||||
| 1031 | public RubyModule getMath() { | ||||
| 1032 | return mathModule; | ||||
| 1033 | } | ||||
| 1034 | void setMath(RubyModule mathModule) { | ||||
| 1035 | this.mathModule = mathModule; | ||||
| 1036 | - } | ||||
| 1037 | + } | ||||
| 1038 | |||||
| 1039 | public RubyModule getMarshal() { | ||||
| 1040 | return marshalModule; | ||||
| 1041 | } | ||||
| 1042 | void setMarshal(RubyModule marshalModule) { | ||||
| 1043 | this.marshalModule = marshalModule; | ||||
| 1044 | - } | ||||
| 1045 | + } | ||||
| 1046 | |||||
| 1047 | public RubyClass getBignum() { | ||||
| 1048 | return bignumClass; | ||||
| 1049 | } | ||||
| 1050 | void setBignum(RubyClass bignumClass) { | ||||
| 1051 | this.bignumClass = bignumClass; | ||||
| 1052 | - } | ||||
| 1053 | + } | ||||
| 1054 | |||||
| 1055 | public RubyClass getDir() { | ||||
| 1056 | return dirClass; | ||||
| 1057 | } | ||||
| 1058 | void setDir(RubyClass dirClass) { | ||||
| 1059 | this.dirClass = dirClass; | ||||
| 1060 | - } | ||||
| 1061 | + } | ||||
| 1062 | |||||
| 1063 | public RubyClass getFile() { | ||||
| 1064 | return fileClass; | ||||
| 1065 | } | ||||
| 1066 | void setFile(RubyClass fileClass) { | ||||
| 1067 | this.fileClass = fileClass; | ||||
| 1068 | - } | ||||
| 1069 | + } | ||||
| 1070 | |||||
| 1071 | public RubyClass getFileStat() { | ||||
| 1072 | return fileStatClass; | ||||
| 1073 | } | ||||
| 1074 | void setFileStat(RubyClass fileStatClass) { | ||||
| 1075 | this.fileStatClass = fileStatClass; | ||||
| 1076 | - } | ||||
| 1077 | + } | ||||
| 1078 | |||||
| 1079 | public RubyModule getFileTest() { | ||||
| 1080 | return fileTestModule; | ||||
| 1081 | @@ -1610,20 +1623,20 @@ | ||||
| 1082 | void setFileTest(RubyModule fileTestModule) { | ||||
| 1083 | this.fileTestModule = fileTestModule; | ||||
| 1084 | } | ||||
| 1085 | - | ||||
| 1086 | + | ||||
| 1087 | public RubyClass getIO() { | ||||
| 1088 | return ioClass; | ||||
| 1089 | } | ||||
| 1090 | void setIO(RubyClass ioClass) { | ||||
| 1091 | this.ioClass = ioClass; | ||||
| 1092 | - } | ||||
| 1093 | + } | ||||
| 1094 | |||||
| 1095 | public RubyClass getThread() { | ||||
| 1096 | return threadClass; | ||||
| 1097 | } | ||||
| 1098 | void setThread(RubyClass threadClass) { | ||||
| 1099 | this.threadClass = threadClass; | ||||
| 1100 | - } | ||||
| 1101 | + } | ||||
| 1102 | |||||
| 1103 | public RubyClass getThreadGroup() { | ||||
| 1104 | return threadGroupClass; | ||||
| 1105 | @@ -1631,7 +1644,7 @@ | ||||
| 1106 | void setThreadGroup(RubyClass threadGroupClass) { | ||||
| 1107 | this.threadGroupClass = threadGroupClass; | ||||
| 1108 | } | ||||
| 1109 | - | ||||
| 1110 | + | ||||
| 1111 | public RubyThreadGroup getDefaultThreadGroup() { | ||||
| 1112 | return defaultThreadGroup; | ||||
| 1113 | } | ||||
| 1114 | @@ -1644,14 +1657,14 @@ | ||||
| 1115 | } | ||||
| 1116 | void setContinuation(RubyClass continuationClass) { | ||||
| 1117 | this.continuationClass = continuationClass; | ||||
| 1118 | - } | ||||
| 1119 | + } | ||||
| 1120 | |||||
| 1121 | public RubyClass getStructClass() { | ||||
| 1122 | return structClass; | ||||
| 1123 | } | ||||
| 1124 | void setStructClass(RubyClass structClass) { | ||||
| 1125 | this.structClass = structClass; | ||||
| 1126 | - } | ||||
| 1127 | + } | ||||
| 1128 | |||||
| 1129 | public IRubyObject getTmsStruct() { | ||||
| 1130 | return tmsStruct; | ||||
| 1131 | @@ -1659,7 +1672,7 @@ | ||||
| 1132 | void setTmsStruct(RubyClass tmsStruct) { | ||||
| 1133 | this.tmsStruct = tmsStruct; | ||||
| 1134 | } | ||||
| 1135 | - | ||||
| 1136 | + | ||||
| 1137 | public IRubyObject getPasswdStruct() { | ||||
| 1138 | return passwdStruct; | ||||
| 1139 | } | ||||
| 1140 | @@ -1679,43 +1692,43 @@ | ||||
| 1141 | } | ||||
| 1142 | void setGC(RubyModule gcModule) { | ||||
| 1143 | this.gcModule = gcModule; | ||||
| 1144 | - } | ||||
| 1145 | + } | ||||
| 1146 | |||||
| 1147 | public RubyModule getObjectSpaceModule() { | ||||
| 1148 | return objectSpaceModule; | ||||
| 1149 | } | ||||
| 1150 | void setObjectSpaceModule(RubyModule objectSpaceModule) { | ||||
| 1151 | this.objectSpaceModule = objectSpaceModule; | ||||
| 1152 | - } | ||||
| 1153 | + } | ||||
| 1154 | |||||
| 1155 | public RubyModule getProcess() { | ||||
| 1156 | return processModule; | ||||
| 1157 | } | ||||
| 1158 | void setProcess(RubyModule processModule) { | ||||
| 1159 | this.processModule = processModule; | ||||
| 1160 | - } | ||||
| 1161 | + } | ||||
| 1162 | |||||
| 1163 | public RubyClass getProcStatus() { | ||||
| 1164 | - return procStatusClass; | ||||
| 1165 | + return procStatusClass; | ||||
| 1166 | } | ||||
| 1167 | void setProcStatus(RubyClass procStatusClass) { | ||||
| 1168 | this.procStatusClass = procStatusClass; | ||||
| 1169 | } | ||||
| 1170 | - | ||||
| 1171 | + | ||||
| 1172 | public RubyModule getProcUID() { | ||||
| 1173 | return procUIDModule; | ||||
| 1174 | } | ||||
| 1175 | void setProcUID(RubyModule procUIDModule) { | ||||
| 1176 | this.procUIDModule = procUIDModule; | ||||
| 1177 | } | ||||
| 1178 | - | ||||
| 1179 | + | ||||
| 1180 | public RubyModule getProcGID() { | ||||
| 1181 | return procGIDModule; | ||||
| 1182 | } | ||||
| 1183 | void setProcGID(RubyModule procGIDModule) { | ||||
| 1184 | this.procGIDModule = procGIDModule; | ||||
| 1185 | } | ||||
| 1186 | - | ||||
| 1187 | + | ||||
| 1188 | public RubyModule getProcSysModule() { | ||||
| 1189 | return procSysModule; | ||||
| 1190 | } | ||||
| 1191 | @@ -1780,11 +1793,11 @@ | ||||
| 1192 | public RubyClass getFatal() { | ||||
| 1193 | return fatal; | ||||
| 1194 | } | ||||
| 1195 | - | ||||
| 1196 | + | ||||
| 1197 | public RubyClass getInterrupt() { | ||||
| 1198 | return interrupt; | ||||
| 1199 | } | ||||
| 1200 | - | ||||
| 1201 | + | ||||
| 1202 | public RubyClass getTypeError() { | ||||
| 1203 | return typeError; | ||||
| 1204 | } | ||||
| 1205 | @@ -1796,7 +1809,7 @@ | ||||
| 1206 | public RubyClass getIndexError() { | ||||
| 1207 | return indexError; | ||||
| 1208 | } | ||||
| 1209 | - | ||||
| 1210 | + | ||||
| 1211 | public RubyClass getSyntaxError() { | ||||
| 1212 | return syntaxError; | ||||
| 1213 | } | ||||
| 1214 | @@ -1804,11 +1817,11 @@ | ||||
| 1215 | public RubyClass getStandardError() { | ||||
| 1216 | return standardError; | ||||
| 1217 | } | ||||
| 1218 | - | ||||
| 1219 | + | ||||
| 1220 | public RubyClass getRuntimeError() { | ||||
| 1221 | return runtimeError; | ||||
| 1222 | } | ||||
| 1223 | - | ||||
| 1224 | + | ||||
| 1225 | public RubyClass getIOError() { | ||||
| 1226 | return ioError; | ||||
| 1227 | } | ||||
| 1228 | @@ -1909,31 +1922,23 @@ | ||||
| 1229 | if (loader == null) { | ||||
| 1230 | loader = ClassLoader.getSystemClassLoader(); | ||||
| 1231 | } | ||||
| 1232 | - | ||||
| 1233 | + | ||||
| 1234 | return loader; | ||||
| 1235 | } | ||||
| 1236 | |||||
| 1237 | public synchronized JRubyClassLoader getJRubyClassLoader() { | ||||
| 1238 | // FIXME: Get rid of laziness and handle restricted access elsewhere | ||||
| 1239 | if (!Ruby.isSecurityRestricted() && jrubyClassLoader == null) { | ||||
| 1240 | - jrubyClassLoader = new JRubyClassLoader(config.getLoader()); | ||||
| 1241 | + jrubyClassLoader = new RuntimeContainer(config.getLoader(), this); | ||||
| 1242 | } | ||||
| 1243 | - | ||||
| 1244 | + | ||||
| 1245 | return jrubyClassLoader; | ||||
| 1246 | } | ||||
| 1247 | |||||
| 1248 | /** Defines a global variable | ||||
| 1249 | */ | ||||
| 1250 | public void defineVariable(final GlobalVariable variable) { | ||||
| 1251 | - globalVariables.define(variable.name(), new IAccessor() { | ||||
| 1252 | - public IRubyObject getValue() { | ||||
| 1253 | - return variable.get(); | ||||
| 1254 | - } | ||||
| 1255 | - | ||||
| 1256 | - public IRubyObject setValue(IRubyObject newValue) { | ||||
| 1257 | - return variable.set(newValue); | ||||
| 1258 | - } | ||||
| 1259 | - }); | ||||
| 1260 | + globalVariables.define(variable.name(), new GlobalVariableAcessor(variable)); | ||||
| 1261 | } | ||||
| 1262 | |||||
| 1263 | /** defines a readonly global variable | ||||
| 1264 | @@ -1942,7 +1947,7 @@ | ||||
| 1265 | public void defineReadonlyVariable(String name, IRubyObject value) { | ||||
| 1266 | globalVariables.defineReadonly(name, new ValueAccessor(value)); | ||||
| 1267 | } | ||||
| 1268 | - | ||||
| 1269 | + | ||||
| 1270 | public Node parseFile(InputStream in, String file, DynamicScope scope) { | ||||
| 1271 | if (parserStats != null) parserStats.addLoadParse(); | ||||
| 1272 | return parser.parse(file, in, scope, new ParserConfiguration(0, false, false, true)); | ||||
| 1273 | @@ -1955,42 +1960,42 @@ | ||||
| 1274 | |||||
| 1275 | public Node parseEval(String content, String file, DynamicScope scope, int lineNumber) { | ||||
| 1276 | byte[] bytes; | ||||
| 1277 | - | ||||
| 1278 | + | ||||
| 1279 | try { | ||||
| 1280 | bytes = content.getBytes(KCode.NONE.getKCode()); | ||||
| 1281 | } catch (UnsupportedEncodingException e) { | ||||
| 1282 | bytes = content.getBytes(); | ||||
| 1283 | } | ||||
| 1284 | - | ||||
| 1285 | + | ||||
| 1286 | if (parserStats != null) parserStats.addEvalParse(); | ||||
| 1287 | - return parser.parse(file, new ByteArrayInputStream(bytes), scope, | ||||
| 1288 | + return parser.parse(file, new ByteArrayInputStream(bytes), scope, | ||||
| 1289 | new ParserConfiguration(lineNumber, false)); | ||||
| 1290 | } | ||||
| 1291 | |||||
| 1292 | @Deprecated | ||||
| 1293 | - public Node parse(String content, String file, DynamicScope scope, int lineNumber, | ||||
| 1294 | + public Node parse(String content, String file, DynamicScope scope, int lineNumber, | ||||
| 1295 | boolean extraPositionInformation) { | ||||
| 1296 | byte[] bytes; | ||||
| 1297 | - | ||||
| 1298 | + | ||||
| 1299 | try { | ||||
| 1300 | bytes = content.getBytes(KCode.NONE.getKCode()); | ||||
| 1301 | } catch (UnsupportedEncodingException e) { | ||||
| 1302 | bytes = content.getBytes(); | ||||
| 1303 | } | ||||
| 1304 | |||||
| 1305 | - return parser.parse(file, new ByteArrayInputStream(bytes), scope, | ||||
| 1306 | + return parser.parse(file, new ByteArrayInputStream(bytes), scope, | ||||
| 1307 | new ParserConfiguration(lineNumber, extraPositionInformation, false)); | ||||
| 1308 | } | ||||
| 1309 | - | ||||
| 1310 | + | ||||
| 1311 | public Node parseEval(ByteList content, String file, DynamicScope scope, int lineNumber) { | ||||
| 1312 | if (parserStats != null) parserStats.addEvalParse(); | ||||
| 1313 | return parser.parse(file, content, scope, new ParserConfiguration(lineNumber, false)); | ||||
| 1314 | } | ||||
| 1315 | |||||
| 1316 | - public Node parse(ByteList content, String file, DynamicScope scope, int lineNumber, | ||||
| 1317 | + public Node parse(ByteList content, String file, DynamicScope scope, int lineNumber, | ||||
| 1318 | boolean extraPositionInformation) { | ||||
| 1319 | if (parserStats != null) parserStats.addJRubyModuleParse(); | ||||
| 1320 | - return parser.parse(file, content, scope, | ||||
| 1321 | + return parser.parse(file, content, scope, | ||||
| 1322 | new ParserConfiguration(lineNumber, extraPositionInformation, false)); | ||||
| 1323 | } | ||||
| 1324 | |||||
| 1325 | @@ -2147,12 +2152,12 @@ | ||||
| 1326 | } | ||||
| 1327 | } | ||||
| 1328 | } | ||||
| 1329 | - | ||||
| 1330 | + | ||||
| 1331 | public void loadFile(String scriptName, InputStream in, boolean wrap) { | ||||
| 1332 | IRubyObject self = wrap ? TopSelfFactory.createTopSelf(this) : getTopSelf(); | ||||
| 1333 | ThreadContext context = getCurrentContext(); | ||||
| 1334 | String file = context.getFile(); | ||||
| 1335 | - | ||||
| 1336 | + | ||||
| 1337 | try { | ||||
| 1338 | secure(4); /* should alter global state */ | ||||
| 1339 | |||||
| 1340 | @@ -2167,20 +2172,20 @@ | ||||
| 1341 | context.setFile(file); | ||||
| 1342 | } | ||||
| 1343 | } | ||||
| 1344 | - | ||||
| 1345 | + | ||||
| 1346 | public void compileAndLoadFile(String filename, InputStream in, boolean wrap) { | ||||
| 1347 | IRubyObject self = wrap ? TopSelfFactory.createTopSelf(this) : getTopSelf(); | ||||
| 1348 | ThreadContext context = getCurrentContext(); | ||||
| 1349 | String file = context.getFile(); | ||||
| 1350 | - | ||||
| 1351 | + | ||||
| 1352 | try { | ||||
| 1353 | secure(4); /* should alter global state */ | ||||
| 1354 | |||||
| 1355 | context.setFile(filename); | ||||
| 1356 | context.preNodeEval(objectClass, self, filename); | ||||
| 1357 | - | ||||
| 1358 | + | ||||
| 1359 | Node scriptNode = parseFile(in, filename, null); | ||||
| 1360 | - | ||||
| 1361 | + | ||||
| 1362 | Script script = tryCompile(scriptNode, new JRubyClassLoader(jrubyClassLoader)); | ||||
| 1363 | if (script == null) { | ||||
| 1364 | System.err.println("Error, could not compile; pass -J-Djruby.jit.logging.verbose=true for more details"); | ||||
| 1365 | @@ -2203,7 +2208,7 @@ | ||||
| 1366 | secure(4); /* should alter global state */ | ||||
| 1367 | |||||
| 1368 | context.preNodeEval(objectClass, self); | ||||
| 1369 | - | ||||
| 1370 | + | ||||
| 1371 | script.load(context, self, IRubyObject.NULL_ARRAY, Block.NULL_BLOCK); | ||||
| 1372 | } catch (JumpException.ReturnJump rj) { | ||||
| 1373 | return; | ||||
| 1374 | @@ -2214,16 +2219,16 @@ | ||||
| 1375 | |||||
| 1376 | public class CallTraceFuncHook extends EventHook { | ||||
| 1377 | private RubyProc traceFunc; | ||||
| 1378 | - | ||||
| 1379 | + | ||||
| 1380 | public void setTraceFunc(RubyProc traceFunc) { | ||||
| 1381 | this.traceFunc = traceFunc; | ||||
| 1382 | } | ||||
| 1383 | - | ||||
| 1384 | + | ||||
| 1385 | public void eventHandler(ThreadContext context, String eventName, String file, int line, String name, IRubyObject type) { | ||||
| 1386 | if (!context.isWithinTrace()) { | ||||
| 1387 | if (file == null) file = "(ruby)"; | ||||
| 1388 | if (type == null) type = getFalse(); | ||||
| 1389 | - | ||||
| 1390 | + | ||||
| 1391 | RubyBinding binding = RubyBinding.newBinding(Ruby.this); | ||||
| 1392 | |||||
| 1393 | context.preTrace(); | ||||
| 1394 | @@ -2246,14 +2251,14 @@ | ||||
| 1395 | return true; | ||||
| 1396 | } | ||||
| 1397 | }; | ||||
| 1398 | - | ||||
| 1399 | + | ||||
| 1400 | private final CallTraceFuncHook callTraceFuncHook = new CallTraceFuncHook(); | ||||
| 1401 | - | ||||
| 1402 | + | ||||
| 1403 | public void addEventHook(EventHook hook) { | ||||
| 1404 | eventHooks.add(hook); | ||||
| 1405 | hasEventHooks = true; | ||||
| 1406 | } | ||||
| 1407 | - | ||||
| 1408 | + | ||||
| 1409 | public void removeEventHook(EventHook hook) { | ||||
| 1410 | eventHooks.remove(hook); | ||||
| 1411 | hasEventHooks = !eventHooks.isEmpty(); | ||||
| 1412 | @@ -2261,15 +2266,15 @@ | ||||
| 1413 | |||||
| 1414 | public void setTraceFunction(RubyProc traceFunction) { | ||||
| 1415 | removeEventHook(callTraceFuncHook); | ||||
| 1416 | - | ||||
| 1417 | + | ||||
| 1418 | if (traceFunction == null) { | ||||
| 1419 | return; | ||||
| 1420 | } | ||||
| 1421 | - | ||||
| 1422 | + | ||||
| 1423 | callTraceFuncHook.setTraceFunc(traceFunction); | ||||
| 1424 | addEventHook(callTraceFuncHook); | ||||
| 1425 | } | ||||
| 1426 | - | ||||
| 1427 | + | ||||
| 1428 | public void callEventHooks(ThreadContext context, RubyEvent event, String file, int line, String name, IRubyObject type) { | ||||
| 1429 | for (EventHook eventHook : eventHooks) { | ||||
| 1430 | if (eventHook.isInterestedInEvent(event)) { | ||||
| 1431 | @@ -2277,11 +2282,11 @@ | ||||
| 1432 | } | ||||
| 1433 | } | ||||
| 1434 | } | ||||
| 1435 | - | ||||
| 1436 | + | ||||
| 1437 | public boolean hasEventHooks() { | ||||
| 1438 | return hasEventHooks; | ||||
| 1439 | } | ||||
| 1440 | - | ||||
| 1441 | + | ||||
| 1442 | public GlobalVariables getGlobalVariables() { | ||||
| 1443 | return globalVariables; | ||||
| 1444 | } | ||||
| 1445 | @@ -2325,7 +2330,7 @@ | ||||
| 1446 | finalizers.put(finalizer, null); | ||||
| 1447 | } | ||||
| 1448 | } | ||||
| 1449 | - | ||||
| 1450 | + | ||||
| 1451 | public void removeInternalFinalizer(Finalizable finalizer) { | ||||
| 1452 | synchronized (internalFinalizersMutex) { | ||||
| 1453 | if (internalFinalizers != null) { | ||||
| 1454 | @@ -2435,15 +2440,15 @@ | ||||
| 1455 | public RubyArray newArray(IRubyObject[] objects) { | ||||
| 1456 | return RubyArray.newArray(this, objects); | ||||
| 1457 | } | ||||
| 1458 | - | ||||
| 1459 | + | ||||
| 1460 | public RubyArray newArrayNoCopy(IRubyObject[] objects) { | ||||
| 1461 | return RubyArray.newArrayNoCopy(this, objects); | ||||
| 1462 | } | ||||
| 1463 | - | ||||
| 1464 | + | ||||
| 1465 | public RubyArray newArrayNoCopyLight(IRubyObject[] objects) { | ||||
| 1466 | return RubyArray.newArrayNoCopyLight(this, objects); | ||||
| 1467 | } | ||||
| 1468 | - | ||||
| 1469 | + | ||||
| 1470 | public RubyArray newArray(List<IRubyObject> list) { | ||||
| 1471 | return RubyArray.newArray(this, list); | ||||
| 1472 | } | ||||
| 1473 | @@ -2459,7 +2464,7 @@ | ||||
| 1474 | public RubyFileStat newFileStat(String filename, boolean lstat) { | ||||
| 1475 | return RubyFileStat.newFileStat(this, filename, lstat); | ||||
| 1476 | } | ||||
| 1477 | - | ||||
| 1478 | + | ||||
| 1479 | public RubyFileStat newFileStat(FileDescriptor descriptor) { | ||||
| 1480 | return RubyFileStat.newFileStat(this, descriptor); | ||||
| 1481 | } | ||||
| 1482 | @@ -2514,7 +2519,7 @@ | ||||
| 1483 | public RubyString newString(String string) { | ||||
| 1484 | return RubyString.newString(this, string); | ||||
| 1485 | } | ||||
| 1486 | - | ||||
| 1487 | + | ||||
| 1488 | public RubyString newString(ByteList byteList) { | ||||
| 1489 | return RubyString.newString(this, byteList); | ||||
| 1490 | } | ||||
| 1491 | @@ -2522,7 +2527,7 @@ | ||||
| 1492 | @Deprecated | ||||
| 1493 | public RubyString newStringShared(ByteList byteList) { | ||||
| 1494 | return RubyString.newStringShared(this, byteList); | ||||
| 1495 | - } | ||||
| 1496 | + } | ||||
| 1497 | |||||
| 1498 | public RubySymbol newSymbol(String name) { | ||||
| 1499 | return symbolTable.getSymbol(name); | ||||
| 1500 | @@ -2533,7 +2538,7 @@ | ||||
| 1501 | * name String. Don't intern your string just to call this version - the | ||||
| 1502 | * overhead of interning will more than wipe out any benefit from the faster | ||||
| 1503 | * lookup. | ||||
| 1504 | - * | ||||
| 1505 | + * | ||||
| 1506 | * @param internedName the symbol name, <em>must</em> be interned! if in | ||||
| 1507 | * doubt, call {@link #newSymbol(String)} instead. | ||||
| 1508 | * @return the symbol for name | ||||
| 1509 | @@ -2550,8 +2555,8 @@ | ||||
| 1510 | |||||
| 1511 | public RaiseException newRuntimeError(String message) { | ||||
| 1512 | return newRaiseException(getRuntimeError(), message); | ||||
| 1513 | - } | ||||
| 1514 | - | ||||
| 1515 | + } | ||||
| 1516 | + | ||||
| 1517 | public RaiseException newArgumentError(String message) { | ||||
| 1518 | return newRaiseException(getArgumentError(), message); | ||||
| 1519 | } | ||||
| 1520 | @@ -2635,14 +2640,14 @@ | ||||
| 1521 | public RaiseException newErrnoEEXISTError(String message) { | ||||
| 1522 | return newRaiseException(getErrno().fastGetClass("EEXIST"), message); | ||||
| 1523 | } | ||||
| 1524 | - | ||||
| 1525 | + | ||||
| 1526 | public RaiseException newErrnoEDOMError(String message) { | ||||
| 1527 | return newRaiseException(getErrno().fastGetClass("EDOM"), "Domain error - " + message); | ||||
| 1528 | - } | ||||
| 1529 | - | ||||
| 1530 | + } | ||||
| 1531 | + | ||||
| 1532 | public RaiseException newErrnoECHILDError() { | ||||
| 1533 | return newRaiseException(getErrno().fastGetClass("ECHILD"), "No child processes"); | ||||
| 1534 | - } | ||||
| 1535 | + } | ||||
| 1536 | |||||
| 1537 | public RaiseException newIndexError(String message) { | ||||
| 1538 | return newRaiseException(getIndexError(), message); | ||||
| 1539 | @@ -2683,7 +2688,7 @@ | ||||
| 1540 | public RaiseException newNotImplementedError(String message) { | ||||
| 1541 | return newRaiseException(getNotImplementedError(), message); | ||||
| 1542 | } | ||||
| 1543 | - | ||||
| 1544 | + | ||||
| 1545 | public RaiseException newInvalidEncoding(String message) { | ||||
| 1546 | return newRaiseException(fastGetClass("Iconv").fastGetClass("InvalidEncoding"), message); | ||||
| 1547 | } | ||||
| 1548 | @@ -2803,6 +2808,14 @@ | ||||
| 1549 | return stackTraces; | ||||
| 1550 | } | ||||
| 1551 | |||||
| 1552 | + public IRubyObject getRuntimeVariable(String name) { | ||||
| 1553 | + return this.runtimeVariables.get(name); | ||||
| 1554 | + } | ||||
| 1555 | + | ||||
| 1556 | + public void setRuntimeVariable(String name, IRubyObject value) { | ||||
| 1557 | + this.runtimeVariables.put(name, value); | ||||
| 1558 | + } | ||||
| 1559 | + | ||||
| 1560 | public void setRandomSeed(long randomSeed) { | ||||
| 1561 | this.randomSeed = randomSeed; | ||||
| 1562 | } | ||||
| 1563 | @@ -2919,27 +2932,27 @@ | ||||
| 1564 | public static boolean isSecurityRestricted() { | ||||
| 1565 | return securityRestricted; | ||||
| 1566 | } | ||||
| 1567 | - | ||||
| 1568 | + | ||||
| 1569 | public static void setSecurityRestricted(boolean restricted) { | ||||
| 1570 | securityRestricted = restricted; | ||||
| 1571 | } | ||||
| 1572 | - | ||||
| 1573 | + | ||||
| 1574 | public POSIX getPosix() { | ||||
| 1575 | return posix; | ||||
| 1576 | } | ||||
| 1577 | - | ||||
| 1578 | + | ||||
| 1579 | public void setRecordSeparatorVar(GlobalVariable recordSeparatorVar) { | ||||
| 1580 | this.recordSeparatorVar = recordSeparatorVar; | ||||
| 1581 | } | ||||
| 1582 | - | ||||
| 1583 | + | ||||
| 1584 | public GlobalVariable getRecordSeparatorVar() { | ||||
| 1585 | return recordSeparatorVar; | ||||
| 1586 | } | ||||
| 1587 | - | ||||
| 1588 | + | ||||
| 1589 | public Set<Script> getJittedMethods() { | ||||
| 1590 | return jittedMethods; | ||||
| 1591 | } | ||||
| 1592 | - | ||||
| 1593 | + | ||||
| 1594 | public ExecutorService getExecutor() { | ||||
| 1595 | return executor; | ||||
| 1596 | } | ||||
| 1597 | @@ -2958,7 +2971,7 @@ | ||||
| 1598 | |||||
| 1599 | private volatile int constantGeneration = 1; | ||||
| 1600 | private final ThreadService threadService; | ||||
| 1601 | - | ||||
| 1602 | + | ||||
| 1603 | private POSIX posix; | ||||
| 1604 | |||||
| 1605 | private int stackTraces = 0; | ||||
| 1606 | @@ -2972,17 +2985,17 @@ | ||||
| 1607 | private Random random = new Random(); | ||||
| 1608 | |||||
| 1609 | private List<EventHook> eventHooks = new Vector<EventHook>(); | ||||
| 1610 | - private boolean hasEventHooks; | ||||
| 1611 | + private boolean hasEventHooks; | ||||
| 1612 | private boolean globalAbortOnExceptionEnabled = false; | ||||
| 1613 | private boolean doNotReverseLookupEnabled = false; | ||||
| 1614 | private volatile boolean objectSpaceEnabled; | ||||
| 1615 | - | ||||
| 1616 | + | ||||
| 1617 | private final Set<Script> jittedMethods = Collections.synchronizedSet(new WeakHashSet<Script>()); | ||||
| 1618 | - | ||||
| 1619 | + | ||||
| 1620 | private static ThreadLocal<Ruby> currentRuntime = new ThreadLocal<Ruby>(); | ||||
| 1621 | - | ||||
| 1622 | + | ||||
| 1623 | private long globalState = 1; | ||||
| 1624 | - | ||||
| 1625 | + | ||||
| 1626 | private int safeLevel = -1; | ||||
| 1627 | |||||
| 1628 | // Default objects | ||||
| 1629 | @@ -2994,7 +3007,7 @@ | ||||
| 1630 | |||||
| 1631 | private IRubyObject verbose; | ||||
| 1632 | private IRubyObject debug; | ||||
| 1633 | - | ||||
| 1634 | + | ||||
| 1635 | private RubyThreadGroup defaultThreadGroup; | ||||
| 1636 | |||||
| 1637 | /** | ||||
| 1638 | @@ -3029,7 +3042,7 @@ | ||||
| 1639 | marshalModule, etcModule, fileTestModule, gcModule, | ||||
| 1640 | objectSpaceModule, processModule, procUIDModule, procGIDModule, | ||||
| 1641 | procSysModule, precisionModule, errnoModule; | ||||
| 1642 | - | ||||
| 1643 | + | ||||
| 1644 | // record separator var, to speed up io ops that use it | ||||
| 1645 | private GlobalVariable recordSeparatorVar; | ||||
| 1646 | |||||
| 1647 | @@ -3047,13 +3060,13 @@ | ||||
| 1648 | // Java support | ||||
| 1649 | private JavaSupport javaSupport; | ||||
| 1650 | private JRubyClassLoader jrubyClassLoader; | ||||
| 1651 | - | ||||
| 1652 | + | ||||
| 1653 | // Management/monitoring | ||||
| 1654 | private BeanManager beanManager; | ||||
| 1655 | |||||
| 1656 | // Parser stats | ||||
| 1657 | private ParserStats parserStats; | ||||
| 1658 | - | ||||
| 1659 | + | ||||
| 1660 | // Compilation | ||||
| 1661 | private final JITCompiler jitCompiler; | ||||
| 1662 | |||||
| 1663 | @@ -3081,7 +3094,8 @@ | ||||
| 1664 | |||||
| 1665 | private LoadService loadService; | ||||
| 1666 | private EncodingService encodingService; | ||||
| 1667 | - private GlobalVariables globalVariables = new GlobalVariables(this); | ||||
| 1668 | + private GlobalVariables globalVariables = new GlobalVariables(); | ||||
| 1669 | + private Map<String, IRubyObject> runtimeVariables = new ConcurrentHashMap<String, IRubyObject>(); | ||||
| 1670 | private RubyWarnings warnings = new RubyWarnings(this); | ||||
| 1671 | |||||
| 1672 | // Contains a list of all blocks (as Procs) that should be called when | ||||
| 1673 | @@ -3105,7 +3119,7 @@ | ||||
| 1674 | * weakly referenced, to be executed on tearDown. | ||||
| 1675 | */ | ||||
| 1676 | private Map<Finalizable, Object> finalizers; | ||||
| 1677 | - | ||||
| 1678 | + | ||||
| 1679 | /** | ||||
| 1680 | * A list of JRuby-internal finalizers, weakly referenced, | ||||
| 1681 | * to be executed on tearDown. | ||||
| 1682 | @@ -3117,7 +3131,8 @@ | ||||
| 1683 | |||||
| 1684 | // mutex that controls modifications of internal finalizers | ||||
| 1685 | private final Object internalFinalizersMutex = new Object(); | ||||
| 1686 | - | ||||
| 1687 | + | ||||
| 1688 | // A thread pool to use for executing this runtime's Ruby threads | ||||
| 1689 | private ExecutorService executor; | ||||
| 1690 | + | ||||
| 1691 | } | ||||
| 1692 | Index: src/org/jruby/RubyModule.java | ||||
| 1693 | =================================================================== | ||||
| 1694 | --- src/org/jruby/RubyModule.java (revision 8091) | ||||
| 1695 | +++ src/org/jruby/RubyModule.java (working copy) | ||||
| 1696 | @@ -190,13 +190,16 @@ | ||||
| 1697 | private final Map<String, CacheEntry> cachedMethods = new ConcurrentHashMap<String, CacheEntry>(12, 0.75f, 1); | ||||
| 1698 | |||||
| 1699 | protected static class Generation { | ||||
| 1700 | - public volatile int hash; | ||||
| 1701 | + private volatile int hash; | ||||
| 1702 | public Generation() { | ||||
| 1703 | hash = hashCode(); | ||||
| 1704 | } | ||||
| 1705 | public synchronized void update() { | ||||
| 1706 | hash = hash + (hashCode() * 31); | ||||
| 1707 | } | ||||
| 1708 | + public int hash() { | ||||
| 1709 | + return hash; | ||||
| 1710 | + } | ||||
| 1711 | } | ||||
| 1712 | protected final Generation generation; | ||||
| 1713 | |||||
| 1714 | @@ -946,7 +949,7 @@ | ||||
| 1715 | } | ||||
| 1716 | |||||
| 1717 | public final int getSerialNumber() { | ||||
| 1718 | - return generation.hash; | ||||
| 1719 | + return generation.hash(); | ||||
| 1720 | } | ||||
| 1721 | |||||
| 1722 | private CacheEntry cacheHit(String name) { | ||||
| 1723 | Index: src/org/jruby/util/RuntimeContainer.java | ||||
| 1724 | =================================================================== | ||||
| 1725 | --- src/org/jruby/util/RuntimeContainer.java (revision 0) | ||||
| 1726 | +++ src/org/jruby/util/RuntimeContainer.java (revision 0) | ||||
| 1727 | @@ -0,0 +1,19 @@ | ||||
| 1728 | +package org.jruby.util; | ||||
| 1729 | + | ||||
| 1730 | +import org.jruby.Ruby; | ||||
| 1731 | + | ||||
| 1732 | +/** | ||||
| 1733 | + * @author Fabio Kung | ||||
| 1734 | + */ | ||||
| 1735 | +public class RuntimeContainer extends JRubyClassLoader { | ||||
| 1736 | + private final Ruby runtime; | ||||
| 1737 | + | ||||
| 1738 | + public RuntimeContainer(ClassLoader parent, Ruby runtime) { | ||||
| 1739 | + super(parent); | ||||
| 1740 | + this.runtime = runtime; | ||||
| 1741 | + } | ||||
| 1742 | + | ||||
| 1743 | + public Ruby getRuntime() { | ||||
| 1744 | + return runtime; | ||||
| 1745 | + } | ||||
| 1746 | +} | ||||
| 1747 | Index: src/org/jruby/util/io/ChannelDescriptor.java | ||||
| 1748 | =================================================================== | ||||
| 1749 | --- src/org/jruby/util/io/ChannelDescriptor.java (revision 8091) | ||||
| 1750 | +++ src/org/jruby/util/io/ChannelDescriptor.java (working copy) | ||||
| 1751 | @@ -94,13 +94,6 @@ | ||||
| 1752 | private AtomicInteger refCounter; | ||||
| 1753 | |||||
| 1754 | /** | ||||
| 1755 | - * Used to work-around blocking problems with STDIN. In most cases <code>null</code>. | ||||
| 1756 | - * See {@link #ChannelDescriptor(InputStream, int, ModeFlags, FileDescriptor)} | ||||
| 1757 | - * for more details. You probably should not use it. | ||||
| 1758 | - */ | ||||
| 1759 | - private InputStream baseInputStream; | ||||
| 1760 | - | ||||
| 1761 | - /** | ||||
| 1762 | * Process streams get Channel.newChannel()ed into FileChannel but are not actually | ||||
| 1763 | * seekable. So instead of just the isSeekable check doing instanceof FileChannel, | ||||
| 1764 | * we must also add this boolean to check, which we set to false when it's known | ||||
| 1765 | @@ -148,28 +141,6 @@ | ||||
| 1766 | } | ||||
| 1767 | |||||
| 1768 | /** | ||||
| 1769 | - * Special constructor to create the ChannelDescriptor out of the stream, file number, | ||||
| 1770 | - * mode flags, and file descriptor object. The channel will be created from the | ||||
| 1771 | - * provided stream. The channel will be kept open until all ChannelDescriptor | ||||
| 1772 | - * references to it have been closed. <b>Note:</b> in most cases, you should not | ||||
| 1773 | - * use this constructor, it's reserved mostly for STDIN. | ||||
| 1774 | - * | ||||
| 1775 | - * @param baseInputStream The stream to create the channel for the new descriptor | ||||
| 1776 | - * @param fileno The file number for the new descriptor | ||||
| 1777 | - * @param originalModes The mode flags for the new descriptor | ||||
| 1778 | - * @param fileDescriptor The java.io.FileDescriptor object for the new descriptor | ||||
| 1779 | - */ | ||||
| 1780 | - public ChannelDescriptor(InputStream baseInputStream, int fileno, ModeFlags originalModes, FileDescriptor fileDescriptor) { | ||||
| 1781 | - // The reason why we need the stream is to be able to invoke available() on it. | ||||
| 1782 | - // STDIN in Java is non-interruptible, non-selectable, and attempt to read | ||||
| 1783 | - // on such stream might lead to thread being blocked without *any* way to unblock it. | ||||
| 1784 | - // That's where available() comes it, so at least we could check whether | ||||
| 1785 | - // anything is available to be read without blocking. | ||||
| 1786 | - this(Channels.newChannel(baseInputStream), fileno, originalModes, fileDescriptor, new AtomicInteger(1), true); | ||||
| 1787 | - this.baseInputStream = baseInputStream; | ||||
| 1788 | - } | ||||
| 1789 | - | ||||
| 1790 | - /** | ||||
| 1791 | * Construct a new ChannelDescriptor with the given channel, file number, | ||||
| 1792 | * and file descriptor object. The channel will be kept open until all ChannelDescriptor | ||||
| 1793 | * references to it have been closed. The channel's capabilities will be used | ||||
| 1794 | @@ -217,30 +188,20 @@ | ||||
| 1795 | } | ||||
| 1796 | |||||
| 1797 | /** | ||||
| 1798 | - * This is intentionally non-public, since it should not be really | ||||
| 1799 | - * used outside of very limited use case (handling of STDIN). | ||||
| 1800 | - * See {@link #ChannelDescriptor(InputStream, int, ModeFlags, FileDescriptor)} | ||||
| 1801 | - * for more info. | ||||
| 1802 | - */ | ||||
| 1803 | - /*package-protected*/ InputStream getBaseInputStream() { | ||||
| 1804 | - return baseInputStream; | ||||
| 1805 | - } | ||||
| 1806 | - | ||||
| 1807 | - /** | ||||
| 1808 | * Whether the channel associated with this descriptor is seekable (i.e. | ||||
| 1809 | * whether it is instanceof FileChannel). | ||||
| 1810 | * | ||||
| 1811 | * @return true if the associated channel is seekable, false otherwise | ||||
| 1812 | */ | ||||
| 1813 | public boolean isSeekable() { | ||||
| 1814 | - return canBeSeekable && channel instanceof FileChannel; | ||||
| 1815 | + return canBeSeekable && getChannel() instanceof FileChannel; | ||||
| 1816 | } | ||||
| 1817 | |||||
| 1818 | /** | ||||
| 1819 | * Set the channel to be explicitly seekable or not, for streams that appear | ||||
| 1820 | * to be seekable with the instanceof FileChannel check. | ||||
| 1821 | * | ||||
| 1822 | - * @param seekable Whether the channel is seekable or not. | ||||
| 1823 | + * @param canBeSeekable Whether the channel is seekable or not. | ||||
| 1824 | */ | ||||
| 1825 | public void setCanBeSeekable(boolean canBeSeekable) { | ||||
| 1826 | this.canBeSeekable = canBeSeekable; | ||||
| 1827 | @@ -251,7 +212,7 @@ | ||||
| 1828 | * for which many operations are simply noops. | ||||
| 1829 | */ | ||||
| 1830 | public boolean isNull() { | ||||
| 1831 | - return channel instanceof NullChannel; | ||||
| 1832 | + return getChannel() instanceof NullChannel; | ||||
| 1833 | } | ||||
| 1834 | |||||
| 1835 | /** | ||||
| 1836 | @@ -261,7 +222,7 @@ | ||||
| 1837 | * @return true if the associated channel is writable, false otherwise | ||||
| 1838 | */ | ||||
| 1839 | public boolean isWritable() { | ||||
| 1840 | - return channel instanceof WritableByteChannel; | ||||
| 1841 | + return getChannel() instanceof WritableByteChannel; | ||||
| 1842 | } | ||||
| 1843 | |||||
| 1844 | /** | ||||
| 1845 | @@ -270,7 +231,7 @@ | ||||
| 1846 | * @return true if the associated channel is open, false otherwise | ||||
| 1847 | */ | ||||
| 1848 | public boolean isOpen() { | ||||
| 1849 | - return channel.isOpen(); | ||||
| 1850 | + return getChannel().isOpen(); | ||||
| 1851 | } | ||||
| 1852 | |||||
| 1853 | /** | ||||
| 1854 | @@ -321,7 +282,7 @@ | ||||
| 1855 | |||||
| 1856 | if (DEBUG) getLogger("ChannelDescriptor").info("Reopen fileno " + newFileno + ", refs now: " + refCounter.get()); | ||||
| 1857 | |||||
| 1858 | - return new ChannelDescriptor(channel, newFileno, originalModes, fileDescriptor, refCounter, canBeSeekable); | ||||
| 1859 | + return new ChannelDescriptor(getChannel(), newFileno, originalModes, fileDescriptor, refCounter, canBeSeekable); | ||||
| 1860 | } | ||||
| 1861 | } | ||||
| 1862 | |||||
| 1863 | @@ -338,7 +299,7 @@ | ||||
| 1864 | |||||
| 1865 | if (DEBUG) getLogger("ChannelDescriptor").info("Reopen fileno " + fileno + ", refs now: " + refCounter.get()); | ||||
| 1866 | |||||
| 1867 | - return new ChannelDescriptor(channel, fileno, originalModes, fileDescriptor, refCounter, canBeSeekable); | ||||
| 1868 | + return new ChannelDescriptor(getChannel(), fileno, originalModes, fileDescriptor, refCounter, canBeSeekable); | ||||
| 1869 | } | ||||
| 1870 | } | ||||
| 1871 | |||||
| 1872 | @@ -386,10 +347,10 @@ | ||||
| 1873 | * @return the new offset into the FileChannel. | ||||
| 1874 | */ | ||||
| 1875 | public long lseek(long offset, int whence) throws IOException, InvalidValueException, PipeException, BadDescriptorException { | ||||
| 1876 | - if (channel instanceof FileChannel) { | ||||
| 1877 | + if (getChannel() instanceof FileChannel) { | ||||
| 1878 | checkOpen(); | ||||
| 1879 | |||||
| 1880 | - FileChannel fileChannel = (FileChannel)channel; | ||||
| 1881 | + FileChannel fileChannel = (FileChannel)getChannel(); | ||||
| 1882 | try { | ||||
| 1883 | long pos; | ||||
| 1884 | switch (whence) { | ||||
| 1885 | @@ -459,7 +420,7 @@ | ||||
| 1886 | public int read(ByteBuffer buffer) throws IOException, BadDescriptorException { | ||||
| 1887 | checkOpen(); | ||||
| 1888 | |||||
| 1889 | - ReadableByteChannel readChannel = (ReadableByteChannel) channel; | ||||
| 1890 | + ReadableByteChannel readChannel = (ReadableByteChannel) getChannel(); | ||||
| 1891 | int bytesRead = 0; | ||||
| 1892 | bytesRead = readChannel.read(buffer); | ||||
| 1893 | |||||
| 1894 | @@ -478,10 +439,10 @@ | ||||
| 1895 | public int internalWrite(ByteBuffer buffer) throws IOException, BadDescriptorException { | ||||
| 1896 | checkOpen(); | ||||
| 1897 | |||||
| 1898 | - WritableByteChannel writeChannel = (WritableByteChannel)channel; | ||||
| 1899 | + WritableByteChannel writeChannel = (WritableByteChannel)getChannel(); | ||||
| 1900 | |||||
| 1901 | if (isSeekable() && originalModes.isAppendable()) { | ||||
| 1902 | - FileChannel fileChannel = (FileChannel)channel; | ||||
| 1903 | + FileChannel fileChannel = (FileChannel)getChannel(); | ||||
| 1904 | fileChannel.position(fileChannel.size()); | ||||
| 1905 | } | ||||
| 1906 | |||||
| 1907 | @@ -677,7 +638,7 @@ | ||||
| 1908 | } | ||||
| 1909 | |||||
| 1910 | // if channel is already closed, we're no longer valid | ||||
| 1911 | - if (!channel.isOpen()) { | ||||
| 1912 | + if (!getChannel().isOpen()) { | ||||
| 1913 | throw new BadDescriptorException(); | ||||
| 1914 | } | ||||
| 1915 | |||||
| 1916 | @@ -687,7 +648,7 @@ | ||||
| 1917 | if (DEBUG) getLogger("ChannelDescriptor").info("Descriptor for fileno " + fileno + " refs: " + count); | ||||
| 1918 | |||||
| 1919 | if (count <= 0) { | ||||
| 1920 | - channel.close(); | ||||
| 1921 | + getChannel().close(); | ||||
| 1922 | } | ||||
| 1923 | } | ||||
| 1924 | } | ||||
| 1925 | Index: src/org/jruby/util/io/ChannelStream.java | ||||
| 1926 | =================================================================== | ||||
| 1927 | --- src/org/jruby/util/io/ChannelStream.java (revision 8091) | ||||
| 1928 | +++ src/org/jruby/util/io/ChannelStream.java (working copy) | ||||
| 1929 | @@ -87,10 +87,9 @@ | ||||
| 1930 | private final static int BULK_READ_SIZE = 16 * 1024; | ||||
| 1931 | private final static ByteBuffer EMPTY_BUFFER = ByteBuffer.allocate(0); | ||||
| 1932 | |||||
| 1933 | - private Ruby runtime; | ||||
| 1934 | protected ModeFlags modes; | ||||
| 1935 | protected boolean sync = false; | ||||
| 1936 | - | ||||
| 1937 | + | ||||
| 1938 | protected volatile ByteBuffer buffer; // r/w buffer | ||||
| 1939 | protected boolean reading; // are we reading or writing? | ||||
| 1940 | private ChannelDescriptor descriptor; | ||||
| 1941 | @@ -100,25 +99,23 @@ | ||||
| 1942 | |||||
| 1943 | private boolean eof = false; | ||||
| 1944 | |||||
| 1945 | - public ChannelStream(Ruby runtime, ChannelDescriptor descriptor, ModeFlags modes, FileDescriptor fileDescriptor) throws InvalidValueException { | ||||
| 1946 | + public ChannelStream(ChannelDescriptor descriptor, ModeFlags modes, FileDescriptor fileDescriptor) throws InvalidValueException { | ||||
| 1947 | descriptor.checkNewModes(modes); | ||||
| 1948 | - | ||||
| 1949 | - this.runtime = runtime; | ||||
| 1950 | + | ||||
| 1951 | this.descriptor = descriptor; | ||||
| 1952 | this.modes = modes; | ||||
| 1953 | this.buffer = ByteBuffer.allocate(BUFSIZE); | ||||
| 1954 | buffer.flip(); | ||||
| 1955 | this.reading = true; | ||||
| 1956 | - | ||||
| 1957 | + | ||||
| 1958 | // this constructor is used by fdopen, so we don't increment descriptor ref count | ||||
| 1959 | } | ||||
| 1960 | |||||
| 1961 | - public ChannelStream(Ruby runtime, ChannelDescriptor descriptor) { | ||||
| 1962 | - this(runtime, descriptor, descriptor.getFileDescriptor()); | ||||
| 1963 | + public ChannelStream(ChannelDescriptor descriptor) { | ||||
| 1964 | + this(descriptor, descriptor.getFileDescriptor()); | ||||
| 1965 | } | ||||
| 1966 | |||||
| 1967 | - public ChannelStream(Ruby runtime, ChannelDescriptor descriptor, FileDescriptor fileDescriptor) { | ||||
| 1968 | - this.runtime = runtime; | ||||
| 1969 | + public ChannelStream(ChannelDescriptor descriptor, FileDescriptor fileDescriptor) { | ||||
| 1970 | this.descriptor = descriptor; | ||||
| 1971 | this.modes = descriptor.getOriginalModes(); | ||||
| 1972 | buffer = ByteBuffer.allocate(BUFSIZE); | ||||
| 1973 | @@ -126,10 +123,9 @@ | ||||
| 1974 | this.reading = true; | ||||
| 1975 | } | ||||
| 1976 | |||||
| 1977 | - public ChannelStream(Ruby runtime, ChannelDescriptor descriptor, ModeFlags modes) throws InvalidValueException { | ||||
| 1978 | + public ChannelStream(ChannelDescriptor descriptor, ModeFlags modes) throws InvalidValueException { | ||||
| 1979 | descriptor.checkNewModes(modes); | ||||
| 1980 | - | ||||
| 1981 | - this.runtime = runtime; | ||||
| 1982 | + | ||||
| 1983 | this.descriptor = descriptor; | ||||
| 1984 | this.modes = modes; | ||||
| 1985 | buffer = ByteBuffer.allocate(BUFSIZE); | ||||
| 1986 | @@ -138,9 +134,9 @@ | ||||
| 1987 | } | ||||
| 1988 | |||||
| 1989 | public Ruby getRuntime() { | ||||
| 1990 | - return runtime; | ||||
| 1991 | + return Ruby.getCurrentRuntime(); | ||||
| 1992 | } | ||||
| 1993 | - | ||||
| 1994 | + | ||||
| 1995 | public void checkReadable() throws IOException { | ||||
| 1996 | if (!modes.isReadable()) throw new IOException("not opened for reading"); | ||||
| 1997 | } | ||||
| 1998 | @@ -152,11 +148,11 @@ | ||||
| 1999 | public void checkPermissionsSubsetOf(ModeFlags subsetModes) { | ||||
| 2000 | subsetModes.isSubsetOf(modes); | ||||
| 2001 | } | ||||
| 2002 | - | ||||
| 2003 | + | ||||
| 2004 | public ModeFlags getModes() { | ||||
| 2005 | return modes; | ||||
| 2006 | } | ||||
| 2007 | - | ||||
| 2008 | + | ||||
| 2009 | public boolean isSync() { | ||||
| 2010 | return sync; | ||||
| 2011 | } | ||||
| 2012 | @@ -176,11 +172,11 @@ | ||||
| 2013 | Thread.sleep(10); | ||||
| 2014 | } | ||||
| 2015 | } | ||||
| 2016 | - | ||||
| 2017 | + | ||||
| 2018 | public boolean readDataBuffered() { | ||||
| 2019 | return reading && buffer.hasRemaining(); | ||||
| 2020 | } | ||||
| 2021 | - | ||||
| 2022 | + | ||||
| 2023 | public boolean writeDataBuffered() { | ||||
| 2024 | return !reading && buffer.position() > 0; | ||||
| 2025 | } | ||||
| 2026 | @@ -202,22 +198,22 @@ | ||||
| 2027 | PARAGRAPH_SEPARATOR : separatorString; | ||||
| 2028 | |||||
| 2029 | descriptor.checkOpen(); | ||||
| 2030 | - | ||||
| 2031 | + | ||||
| 2032 | if (feof()) { | ||||
| 2033 | return null; | ||||
| 2034 | } | ||||
| 2035 | - | ||||
| 2036 | + | ||||
| 2037 | int c = read(); | ||||
| 2038 | - | ||||
| 2039 | + | ||||
| 2040 | if (c == -1) { | ||||
| 2041 | return null; | ||||
| 2042 | } | ||||
| 2043 | - | ||||
| 2044 | + | ||||
| 2045 | // unread back | ||||
| 2046 | buffer.position(buffer.position() - 1); | ||||
| 2047 | |||||
| 2048 | ByteList buf = new ByteList(40); | ||||
| 2049 | - | ||||
| 2050 | + | ||||
| 2051 | byte first = separator.bytes[separator.begin]; | ||||
| 2052 | |||||
| 2053 | LineLoop : while (true) { | ||||
| 2054 | @@ -225,7 +221,7 @@ | ||||
| 2055 | byte[] bytes = buffer.array(); | ||||
| 2056 | int offset = buffer.position(); | ||||
| 2057 | int max = buffer.limit(); | ||||
| 2058 | - | ||||
| 2059 | + | ||||
| 2060 | // iterate over remainder of buffer until we find a match | ||||
| 2061 | for (int i = offset; i < max; i++) { | ||||
| 2062 | c = bytes[i]; | ||||
| 2063 | @@ -240,13 +236,13 @@ | ||||
| 2064 | break ReadLoop; | ||||
| 2065 | } | ||||
| 2066 | } | ||||
| 2067 | - | ||||
| 2068 | + | ||||
| 2069 | // no match, append remainder of buffer and continue with next block | ||||
| 2070 | buf.append(bytes, offset, buffer.remaining()); | ||||
| 2071 | int read = refillBuffer(); | ||||
| 2072 | if (read == -1) break LineLoop; | ||||
| 2073 | } | ||||
| 2074 | - | ||||
| 2075 | + | ||||
| 2076 | // found a match above, check if remaining separator characters match, appending as we go | ||||
| 2077 | for (int i = 0; i < separator.realSize; i++) { | ||||
| 2078 | if (c == -1) { | ||||
| 2079 | @@ -272,7 +268,7 @@ | ||||
| 2080 | |||||
| 2081 | return buf; | ||||
| 2082 | } | ||||
| 2083 | - | ||||
| 2084 | + | ||||
| 2085 | /** | ||||
| 2086 | * An version of read that reads all bytes up to and including a terminator byte. | ||||
| 2087 | * <p> | ||||
| 2088 | @@ -282,7 +278,7 @@ | ||||
| 2089 | * @param dst The output buffer. | ||||
| 2090 | * @param terminator The byte to terminate reading. | ||||
| 2091 | * @return The number of bytes read, or -1 if EOF is reached. | ||||
| 2092 | - * | ||||
| 2093 | + * | ||||
| 2094 | * @throws java.io.IOException | ||||
| 2095 | * @throws org.jruby.util.io.BadDescriptorException | ||||
| 2096 | */ | ||||
| 2097 | @@ -290,7 +286,7 @@ | ||||
| 2098 | checkReadable(); | ||||
| 2099 | ensureRead(); | ||||
| 2100 | descriptor.checkOpen(); | ||||
| 2101 | - | ||||
| 2102 | + | ||||
| 2103 | int totalRead = 0; | ||||
| 2104 | boolean found = false; | ||||
| 2105 | if (ungotc != -1) { | ||||
| 2106 | @@ -324,7 +320,7 @@ | ||||
| 2107 | } | ||||
| 2108 | return totalRead; | ||||
| 2109 | } | ||||
| 2110 | - | ||||
| 2111 | + | ||||
| 2112 | public synchronized ByteList readall() throws IOException, BadDescriptorException { | ||||
| 2113 | if (descriptor.isSeekable()) { | ||||
| 2114 | invalidateBuffer(); | ||||
| 2115 | @@ -336,7 +332,7 @@ | ||||
| 2116 | } | ||||
| 2117 | left += ungotc != -1 ? 1 : 0; | ||||
| 2118 | ByteList result = new ByteList((int) left); | ||||
| 2119 | - ByteBuffer buf = ByteBuffer.wrap(result.unsafeBytes(), | ||||
| 2120 | + ByteBuffer buf = ByteBuffer.wrap(result.unsafeBytes(), | ||||
| 2121 | result.begin(), (int) left); | ||||
| 2122 | if (ungotc != -1) { | ||||
| 2123 | buf.put((byte) ungotc); | ||||
| 2124 | @@ -358,7 +354,7 @@ | ||||
| 2125 | |||||
| 2126 | ByteList byteList = new ByteList(); | ||||
| 2127 | ByteList read = fread(BUFSIZE); | ||||
| 2128 | - | ||||
| 2129 | + | ||||
| 2130 | if (read == null) { | ||||
| 2131 | eof = true; | ||||
| 2132 | return byteList; | ||||
| 2133 | @@ -370,14 +366,14 @@ | ||||
| 2134 | } | ||||
| 2135 | |||||
| 2136 | return byteList; | ||||
| 2137 | - } | ||||
| 2138 | + } | ||||
| 2139 | } | ||||
| 2140 | - | ||||
| 2141 | + | ||||
| 2142 | /** | ||||
| 2143 | * <p>Close IO handler resources.</p> | ||||
| 2144 | - * @throws IOException | ||||
| 2145 | - * @throws BadDescriptorException | ||||
| 2146 | - * | ||||
| 2147 | + * @throws IOException | ||||
| 2148 | + * @throws BadDescriptorException | ||||
| 2149 | + * | ||||
| 2150 | * @see org.jruby.util.IOHandler#close() | ||||
| 2151 | */ | ||||
| 2152 | public synchronized void fclose() throws IOException, BadDescriptorException { | ||||
| 2153 | @@ -408,7 +404,7 @@ | ||||
| 2154 | /** | ||||
| 2155 | * Internal close, to safely work for finalizing. | ||||
| 2156 | * @param finalizing true if this is in a finalizing context | ||||
| 2157 | - * @throws IOException | ||||
| 2158 | + * @throws IOException | ||||
| 2159 | * @throws BadDescriptorException | ||||
| 2160 | */ | ||||
| 2161 | private void closeForFinalize() { | ||||
| 2162 | @@ -422,8 +418,8 @@ | ||||
| 2163 | } | ||||
| 2164 | |||||
| 2165 | /** | ||||
| 2166 | - * @throws IOException | ||||
| 2167 | - * @throws BadDescriptorException | ||||
| 2168 | + * @throws IOException | ||||
| 2169 | + * @throws BadDescriptorException | ||||
| 2170 | * @see org.jruby.util.IOHandler#flush() | ||||
| 2171 | */ | ||||
| 2172 | public synchronized int fflush() throws IOException, BadDescriptorException { | ||||
| 2173 | @@ -435,14 +431,14 @@ | ||||
| 2174 | } | ||||
| 2175 | return 0; | ||||
| 2176 | } | ||||
| 2177 | - | ||||
| 2178 | + | ||||
| 2179 | /** | ||||
| 2180 | * Flush the write buffer to the channel (if needed) | ||||
| 2181 | * @throws IOException | ||||
| 2182 | */ | ||||
| 2183 | private void flushWrite() throws IOException, BadDescriptorException { | ||||
| 2184 | if (reading || !modes.isWritable() || buffer.position() == 0) return; // Don't bother | ||||
| 2185 | - | ||||
| 2186 | + | ||||
| 2187 | int len = buffer.position(); | ||||
| 2188 | buffer.flip(); | ||||
| 2189 | int n = descriptor.write(buffer); | ||||
| 2190 | @@ -452,7 +448,7 @@ | ||||
| 2191 | } | ||||
| 2192 | buffer.clear(); | ||||
| 2193 | } | ||||
| 2194 | - | ||||
| 2195 | + | ||||
| 2196 | /** | ||||
| 2197 | * Flush the write buffer to the channel (if needed) | ||||
| 2198 | * @throws IOException | ||||
| 2199 | @@ -494,12 +490,7 @@ | ||||
| 2200 | * @see org.jruby.util.IOHandler#getInputStream() | ||||
| 2201 | */ | ||||
| 2202 | public InputStream newInputStream() { | ||||
| 2203 | - InputStream in = descriptor.getBaseInputStream(); | ||||
| 2204 | - if (in == null) { | ||||
| 2205 | - return new BufferedInputStream(Channels.newInputStream((ReadableByteChannel)descriptor.getChannel())); | ||||
| 2206 | - } else { | ||||
| 2207 | - return in; | ||||
| 2208 | - } | ||||
| 2209 | + return new BufferedInputStream(Channels.newInputStream((ReadableByteChannel) descriptor.getChannel())); | ||||
| 2210 | } | ||||
| 2211 | |||||
| 2212 | /** | ||||
| 2213 | @@ -508,28 +499,28 @@ | ||||
| 2214 | public OutputStream newOutputStream() { | ||||
| 2215 | return new BufferedOutputStream(Channels.newOutputStream((WritableByteChannel)descriptor.getChannel())); | ||||
| 2216 | } | ||||
| 2217 | - | ||||
| 2218 | + | ||||
| 2219 | public void clearerr() { | ||||
| 2220 | eof = false; | ||||
| 2221 | } | ||||
| 2222 | - | ||||
| 2223 | + | ||||
| 2224 | /** | ||||
| 2225 | - * @throws IOException | ||||
| 2226 | - * @throws BadDescriptorException | ||||
| 2227 | + * @throws IOException | ||||
| 2228 | + * @throws BadDescriptorException | ||||
| 2229 | * @see org.jruby.util.IOHandler#isEOF() | ||||
| 2230 | */ | ||||
| 2231 | public boolean feof() throws IOException, BadDescriptorException { | ||||
| 2232 | checkReadable(); | ||||
| 2233 | - | ||||
| 2234 | + | ||||
| 2235 | if (eof) { | ||||
| 2236 | return true; | ||||
| 2237 | } else { | ||||
| 2238 | return false; | ||||
| 2239 | } | ||||
| 2240 | } | ||||
| 2241 | - | ||||
| 2242 | + | ||||
| 2243 | /** | ||||
| 2244 | - * @throws IOException | ||||
| 2245 | + * @throws IOException | ||||
| 2246 | * @see org.jruby.util.IOHandler#pos() | ||||
| 2247 | */ | ||||
| 2248 | public synchronized long fgetpos() throws IOException, PipeException, InvalidValueException, BadDescriptorException { | ||||
| 2249 | @@ -550,14 +541,14 @@ | ||||
| 2250 | throw new PipeException(); | ||||
| 2251 | } | ||||
| 2252 | } | ||||
| 2253 | - | ||||
| 2254 | + | ||||
| 2255 | /** | ||||
| 2256 | * Implementation of libc "lseek", which seeks on seekable streams, raises | ||||
| 2257 | * EPIPE if the fd is assocated with a pipe, socket, or FIFO, and doesn't | ||||
| 2258 | * do anything for other cases (like stdio). | ||||
| 2259 | - * | ||||
| 2260 | - * @throws IOException | ||||
| 2261 | - * @throws InvalidValueException | ||||
| 2262 | + * | ||||
| 2263 | + * @throws IOException | ||||
| 2264 | + * @throws InvalidValueException | ||||
| 2265 | * @see org.jruby.util.IOHandler#seek(long, int) | ||||
| 2266 | */ | ||||
| 2267 | public synchronized void lseek(long offset, int type) throws IOException, InvalidValueException, PipeException, BadDescriptorException { | ||||
| 2268 | @@ -636,7 +627,7 @@ | ||||
| 2269 | reading = true; | ||||
| 2270 | } | ||||
| 2271 | } | ||||
| 2272 | - | ||||
| 2273 | + | ||||
| 2274 | private void resetForWrite() throws IOException { | ||||
| 2275 | if (descriptor.isSeekable()) { | ||||
| 2276 | FileChannel fileChannel = (FileChannel)descriptor.getChannel(); | ||||
| 2277 | @@ -648,7 +639,7 @@ | ||||
| 2278 | buffer.clear(); | ||||
| 2279 | reading = false; | ||||
| 2280 | } | ||||
| 2281 | - | ||||
| 2282 | + | ||||
| 2283 | /** | ||||
| 2284 | * Ensure buffer is ready for writing. | ||||
| 2285 | * @throws IOException | ||||
| 2286 | @@ -661,25 +652,25 @@ | ||||
| 2287 | public synchronized ByteList read(int number) throws IOException, BadDescriptorException { | ||||
| 2288 | checkReadable(); | ||||
| 2289 | ensureReadNonBuffered(); | ||||
| 2290 | - | ||||
| 2291 | + | ||||
| 2292 | ByteList byteList = new ByteList(number); | ||||
| 2293 | - | ||||
| 2294 | + | ||||
| 2295 | // TODO this should entry into error handling somewhere | ||||
| 2296 | int bytesRead = descriptor.read(number, byteList); | ||||
| 2297 | - | ||||
| 2298 | + | ||||
| 2299 | if (bytesRead == -1) { | ||||
| 2300 | eof = true; | ||||
| 2301 | } | ||||
| 2302 | - | ||||
| 2303 | + | ||||
| 2304 | return byteList; | ||||
| 2305 | } | ||||
| 2306 | |||||
| 2307 | private ByteList bufferedRead(int number) throws IOException, BadDescriptorException { | ||||
| 2308 | checkReadable(); | ||||
| 2309 | ensureRead(); | ||||
| 2310 | - | ||||
| 2311 | + | ||||
| 2312 | ByteList result = new ByteList(0); | ||||
| 2313 | - | ||||
| 2314 | + | ||||
| 2315 | int len = -1; | ||||
| 2316 | if (buffer.hasRemaining()) { // already have some bytes buffered | ||||
| 2317 | len = (number <= buffer.remaining()) ? number : buffer.remaining(); | ||||
| 2318 | @@ -704,26 +695,26 @@ | ||||
| 2319 | break; | ||||
| 2320 | } | ||||
| 2321 | } | ||||
| 2322 | - | ||||
| 2323 | + | ||||
| 2324 | // | ||||
| 2325 | // Complete the request by filling the read buffer first | ||||
| 2326 | // | ||||
| 2327 | while (!done && result.length() != number) { | ||||
| 2328 | int read = refillBuffer(); | ||||
| 2329 | - | ||||
| 2330 | + | ||||
| 2331 | if (read == -1) { | ||||
| 2332 | eof = true; | ||||
| 2333 | break; | ||||
| 2334 | } else if (read == 0) { | ||||
| 2335 | break; | ||||
| 2336 | } | ||||
| 2337 | - | ||||
| 2338 | + | ||||
| 2339 | // append what we read into our buffer and allow the loop to continue | ||||
| 2340 | int desired = number - result.length(); | ||||
| 2341 | len = (desired < read) ? desired : read; | ||||
| 2342 | result.append(buffer, len); | ||||
| 2343 | } | ||||
| 2344 | - | ||||
| 2345 | + | ||||
| 2346 | if (result.length() == 0 && number != 0) { | ||||
| 2347 | if (eof) { | ||||
| 2348 | throw new EOFException(); | ||||
| 2349 | @@ -731,10 +722,10 @@ | ||||
| 2350 | } | ||||
| 2351 | return result; | ||||
| 2352 | } | ||||
| 2353 | - | ||||
| 2354 | + | ||||
| 2355 | private int bufferedRead() throws IOException, BadDescriptorException { | ||||
| 2356 | ensureRead(); | ||||
| 2357 | - | ||||
| 2358 | + | ||||
| 2359 | if (!buffer.hasRemaining()) { | ||||
| 2360 | int len = refillBuffer(); | ||||
| 2361 | if (len == -1) { | ||||
| 2362 | @@ -746,42 +737,42 @@ | ||||
| 2363 | } | ||||
| 2364 | return buffer.get() & 0xFF; | ||||
| 2365 | } | ||||
| 2366 | - | ||||
| 2367 | + | ||||
| 2368 | /** | ||||
| 2369 | - * @throws IOException | ||||
| 2370 | - * @throws BadDescriptorException | ||||
| 2371 | + * @throws IOException | ||||
| 2372 | + * @throws BadDescriptorException | ||||
| 2373 | * @see org.jruby.util.IOHandler#syswrite(String buf) | ||||
| 2374 | */ | ||||
| 2375 | private int bufferedWrite(ByteList buf) throws IOException, BadDescriptorException { | ||||
| 2376 | getRuntime().secure(4); | ||||
| 2377 | checkWritable(); | ||||
| 2378 | ensureWrite(); | ||||
| 2379 | - | ||||
| 2380 | + | ||||
| 2381 | // Ruby ignores empty syswrites | ||||
| 2382 | if (buf == null || buf.length() == 0) return 0; | ||||
| 2383 | - | ||||
| 2384 | + | ||||
| 2385 | if (buf.length() > buffer.capacity()) { // Doesn't fit in buffer. Write immediately. | ||||
| 2386 | flushWrite(); // ensure nothing left to write | ||||
| 2387 | - | ||||
| 2388 | |||||
| 2389 | + | ||||
| 2390 | int n = descriptor.write(ByteBuffer.wrap(buf.unsafeBytes(), buf.begin(), buf.length())); | ||||
| 2391 | if(n != buf.length()) { | ||||
| 2392 | // TODO: check the return value here | ||||
| 2393 | } | ||||
| 2394 | } else { | ||||
| 2395 | if (buf.length() > buffer.remaining()) flushWrite(); | ||||
| 2396 | - | ||||
| 2397 | + | ||||
| 2398 | buffer.put(buf.unsafeBytes(), buf.begin(), buf.length()); | ||||
| 2399 | } | ||||
| 2400 | - | ||||
| 2401 | + | ||||
| 2402 | if (isSync()) sync(); | ||||
| 2403 | - | ||||
| 2404 | + | ||||
| 2405 | return buf.realSize; | ||||
| 2406 | } | ||||
| 2407 | - | ||||
| 2408 | + | ||||
| 2409 | /** | ||||
| 2410 | - * @throws IOException | ||||
| 2411 | - * @throws BadDescriptorException | ||||
| 2412 | + * @throws IOException | ||||
| 2413 | + * @throws BadDescriptorException | ||||
| 2414 | * @see org.jruby.util.IOHandler#syswrite(String buf) | ||||
| 2415 | */ | ||||
| 2416 | private int bufferedWrite(int c) throws IOException, BadDescriptorException { | ||||
| 2417 | @@ -790,14 +781,14 @@ | ||||
| 2418 | ensureWrite(); | ||||
| 2419 | |||||
| 2420 | if (!buffer.hasRemaining()) flushWrite(); | ||||
| 2421 | - | ||||
| 2422 | + | ||||
| 2423 | buffer.put((byte) c); | ||||
| 2424 | - | ||||
| 2425 | + | ||||
| 2426 | if (isSync()) sync(); | ||||
| 2427 | - | ||||
| 2428 | + | ||||
| 2429 | return 1; | ||||
| 2430 | } | ||||
| 2431 | - | ||||
| 2432 | + | ||||
| 2433 | public synchronized void ftruncate(long newLength) throws IOException, | ||||
| 2434 | BadDescriptorException, InvalidValueException { | ||||
| 2435 | Channel ch = descriptor.getChannel(); | ||||
| 2436 | @@ -810,20 +801,20 @@ | ||||
| 2437 | // truncate can't lengthen files, so we save position, seek/write, and go back | ||||
| 2438 | long position = fileChannel.position(); | ||||
| 2439 | int difference = (int)(newLength - fileChannel.size()); | ||||
| 2440 | - | ||||
| 2441 | + | ||||
| 2442 | fileChannel.position(fileChannel.size()); | ||||
| 2443 | // FIXME: This worries me a bit, since it could allocate a lot with a large newLength | ||||
| 2444 | fileChannel.write(ByteBuffer.allocate(difference)); | ||||
| 2445 | fileChannel.position(position); | ||||
| 2446 | } else { | ||||
| 2447 | fileChannel.truncate(newLength); | ||||
| 2448 | - } | ||||
| 2449 | + } | ||||
| 2450 | } | ||||
| 2451 | - | ||||
| 2452 | + | ||||
| 2453 | /** | ||||
| 2454 | * Invalidate buffer before a position change has occurred (e.g. seek), | ||||
| 2455 | * flushing writes if required, and correcting file position if reading | ||||
| 2456 | - * @throws IOException | ||||
| 2457 | + * @throws IOException | ||||
| 2458 | */ | ||||
| 2459 | private void invalidateBuffer() throws IOException, BadDescriptorException { | ||||
| 2460 | if (!reading) flushWrite(); | ||||
| 2461 | @@ -862,13 +853,13 @@ | ||||
| 2462 | if (c == -1) { | ||||
| 2463 | return -1; | ||||
| 2464 | } | ||||
| 2465 | - | ||||
| 2466 | + | ||||
| 2467 | // putting a bit back, so we're not at EOF anymore | ||||
| 2468 | eof = false; | ||||
| 2469 | |||||
| 2470 | // save the ungot | ||||
| 2471 | ungotc = c; | ||||
| 2472 | - | ||||
| 2473 | + | ||||
| 2474 | return c; | ||||
| 2475 | } | ||||
| 2476 | |||||
| 2477 | @@ -876,7 +867,7 @@ | ||||
| 2478 | if (eof) { | ||||
| 2479 | return -1; | ||||
| 2480 | } | ||||
| 2481 | - | ||||
| 2482 | + | ||||
| 2483 | checkReadable(); | ||||
| 2484 | |||||
| 2485 | int c = read(); | ||||
| 2486 | @@ -885,7 +876,7 @@ | ||||
| 2487 | eof = true; | ||||
| 2488 | return c; | ||||
| 2489 | } | ||||
| 2490 | - | ||||
| 2491 | + | ||||
| 2492 | return c & 0xff; | ||||
| 2493 | } | ||||
| 2494 | |||||
| 2495 | @@ -896,12 +887,12 @@ | ||||
| 2496 | getRuntime().secure(4); | ||||
| 2497 | checkWritable(); | ||||
| 2498 | ensureWrite(); | ||||
| 2499 | - | ||||
| 2500 | + | ||||
| 2501 | // Ruby ignores empty syswrites | ||||
| 2502 | if (buf == null || buf.length() == 0) return 0; | ||||
| 2503 | - | ||||
| 2504 | + | ||||
| 2505 | if (buffer.position() != 0 && !flushWrite(false)) return 0; | ||||
| 2506 | - | ||||
| 2507 | + | ||||
| 2508 | if (descriptor.getChannel() instanceof SelectableChannel) { | ||||
| 2509 | SelectableChannel selectableChannel = (SelectableChannel)descriptor.getChannel(); | ||||
| 2510 | synchronized (selectableChannel.blockingLock()) { | ||||
| 2511 | @@ -1002,13 +993,13 @@ | ||||
| 2512 | } else { | ||||
| 2513 | // otherwise, we try an unbuffered read to get whatever's available | ||||
| 2514 | return read(number); | ||||
| 2515 | - } | ||||
| 2516 | + } | ||||
| 2517 | } | ||||
| 2518 | |||||
| 2519 | public synchronized int read() throws IOException, BadDescriptorException { | ||||
| 2520 | try { | ||||
| 2521 | descriptor.checkOpen(); | ||||
| 2522 | - | ||||
| 2523 | + | ||||
| 2524 | if (ungotc >= 0) { | ||||
| 2525 | int c = ungotc; | ||||
| 2526 | ungotc = -1; | ||||
| 2527 | @@ -1021,11 +1012,11 @@ | ||||
| 2528 | return -1; | ||||
| 2529 | } | ||||
| 2530 | } | ||||
| 2531 | - | ||||
| 2532 | + | ||||
| 2533 | public ChannelDescriptor getDescriptor() { | ||||
| 2534 | return descriptor; | ||||
| 2535 | } | ||||
| 2536 | - | ||||
| 2537 | + | ||||
| 2538 | public void setBlocking(boolean block) throws IOException { | ||||
| 2539 | if (!(descriptor.getChannel() instanceof SelectableChannel)) { | ||||
| 2540 | return; | ||||
| 2541 | @@ -1059,7 +1050,7 @@ | ||||
| 2542 | if (descriptor.isOpen()) { | ||||
| 2543 | descriptor.close(); | ||||
| 2544 | } | ||||
| 2545 | - | ||||
| 2546 | + | ||||
| 2547 | if (path.equals("/dev/null") || path.equalsIgnoreCase("nul:") || path.equalsIgnoreCase("nul")) { | ||||
| 2548 | descriptor = new ChannelDescriptor(new NullChannel(), descriptor.getFileno(), modes, new FileDescriptor()); | ||||
| 2549 | } else { | ||||
| 2550 | @@ -1083,27 +1074,27 @@ | ||||
| 2551 | RandomAccessFile file = new RandomAccessFile(theFile, modes.toJavaModeString()); | ||||
| 2552 | |||||
| 2553 | if (modes.isTruncate()) file.setLength(0L); | ||||
| 2554 | - | ||||
| 2555 | + | ||||
| 2556 | descriptor = new ChannelDescriptor(file.getChannel(), descriptor.getFileno(), modes, file.getFD()); | ||||
| 2557 | - | ||||
| 2558 | + | ||||
| 2559 | if (modes.isAppendable()) lseek(0, SEEK_END); | ||||
| 2560 | } | ||||
| 2561 | } | ||||
| 2562 | - | ||||
| 2563 | + | ||||
| 2564 | public static Stream fopen(Ruby runtime, String path, ModeFlags modes) throws FileNotFoundException, DirectoryAsFileException, FileExistsException, IOException, InvalidValueException, PipeException, BadDescriptorException { | ||||
| 2565 | String cwd = runtime.getCurrentDirectory(); | ||||
| 2566 | - | ||||
| 2567 | + | ||||
| 2568 | ChannelDescriptor descriptor = ChannelDescriptor.open(cwd, path, modes); | ||||
| 2569 | - | ||||
| 2570 | + | ||||
| 2571 | Stream stream = fdopen(runtime, descriptor, modes); | ||||
| 2572 | - | ||||
| 2573 | + | ||||
| 2574 | if (modes.isAppendable()) stream.lseek(0, Stream.SEEK_END); | ||||
| 2575 | - | ||||
| 2576 | + | ||||
| 2577 | return stream; | ||||
| 2578 | } | ||||
| 2579 | - | ||||
| 2580 | + | ||||
| 2581 | public static Stream fdopen(Ruby runtime, ChannelDescriptor descriptor, ModeFlags modes) throws InvalidValueException { | ||||
| 2582 | - Stream handler = new ChannelStream(runtime, descriptor, modes, descriptor.getFileDescriptor()); | ||||
| 2583 | + Stream handler = new ChannelStream(descriptor, modes, descriptor.getFileDescriptor()); | ||||
| 2584 | |||||
| 2585 | return handler; | ||||
| 2586 | } | ||||
| 2587 | Index: src/org/jruby/RubyGlobal.java | ||||
| 2588 | =================================================================== | ||||
| 2589 | --- src/org/jruby/RubyGlobal.java (revision 8091) | ||||
| 2590 | +++ src/org/jruby/RubyGlobal.java (working copy) | ||||
| 2591 | @@ -43,29 +43,28 @@ | ||||
| 2592 | import org.jruby.common.IRubyWarnings.ID; | ||||
| 2593 | import org.jruby.environment.OSEnvironmentReaderExcepton; | ||||
| 2594 | import org.jruby.environment.OSEnvironment; | ||||
| 2595 | -import org.jruby.internal.runtime.ValueAccessor; | ||||
| 2596 | +import org.jruby.internal.runtime.RuntimeVariableAccessor; | ||||
| 2597 | import org.jruby.javasupport.JavaUtil; | ||||
| 2598 | import org.jruby.javasupport.util.RuntimeHelpers; | ||||
| 2599 | import org.jruby.runtime.Constants; | ||||
| 2600 | import org.jruby.runtime.GlobalVariable; | ||||
| 2601 | -import org.jruby.runtime.IAccessor; | ||||
| 2602 | import org.jruby.runtime.ReadonlyGlobalVariable; | ||||
| 2603 | import org.jruby.runtime.ThreadContext; | ||||
| 2604 | import org.jruby.runtime.builtin.IRubyObject; | ||||
| 2605 | import org.jruby.util.KCode; | ||||
| 2606 | |||||
| 2607 | /** This class initializes global variables and constants. | ||||
| 2608 | - * | ||||
| 2609 | + * | ||||
| 2610 | * @author jpetersen | ||||
| 2611 | */ | ||||
| 2612 | public class RubyGlobal { | ||||
| 2613 | - | ||||
| 2614 | + | ||||
| 2615 | /** | ||||
| 2616 | * Obligate string-keyed and string-valued hash, used for ENV and ENV_JAVA | ||||
| 2617 | - * | ||||
| 2618 | + * | ||||
| 2619 | */ | ||||
| 2620 | public static class StringOnlyRubyHash extends RubyHash { | ||||
| 2621 | - | ||||
| 2622 | + | ||||
| 2623 | public StringOnlyRubyHash(Ruby runtime, Map valueMap, IRubyObject defaultValue) { | ||||
| 2624 | super(runtime, valueMap, defaultValue); | ||||
| 2625 | } | ||||
| 2626 | @@ -95,26 +94,26 @@ | ||||
| 2627 | if (value.isNil()) { | ||||
| 2628 | return super.delete(context, key, org.jruby.runtime.Block.NULL_BLOCK); | ||||
| 2629 | } | ||||
| 2630 | - | ||||
| 2631 | + | ||||
| 2632 | //return super.aset(getRuntime().newString("sadfasdF"), getRuntime().newString("sadfasdF")); | ||||
| 2633 | return super.op_aset(context, RuntimeHelpers.invoke(context, key, "to_str"), | ||||
| 2634 | value.isNil() ? getRuntime().getNil() : RuntimeHelpers.invoke(context, value, "to_str")); | ||||
| 2635 | } | ||||
| 2636 | - | ||||
| 2637 | + | ||||
| 2638 | @JRubyMethod | ||||
| 2639 | @Override | ||||
| 2640 | public IRubyObject to_s(){ | ||||
| 2641 | return getRuntime().newString("ENV"); | ||||
| 2642 | } | ||||
| 2643 | } | ||||
| 2644 | - | ||||
| 2645 | + | ||||
| 2646 | public static void createGlobals(ThreadContext context, Ruby runtime) { | ||||
| 2647 | runtime.defineGlobalConstant("TOPLEVEL_BINDING", runtime.newBinding()); | ||||
| 2648 | - | ||||
| 2649 | + | ||||
| 2650 | runtime.defineGlobalConstant("TRUE", runtime.getTrue()); | ||||
| 2651 | runtime.defineGlobalConstant("FALSE", runtime.getFalse()); | ||||
| 2652 | runtime.defineGlobalConstant("NIL", runtime.getNil()); | ||||
| 2653 | - | ||||
| 2654 | + | ||||
| 2655 | // define ARGV and $* for this runtime | ||||
| 2656 | RubyArray argvArray = runtime.newArray(); | ||||
| 2657 | String[] argv = runtime.getInstanceConfig().getArgv(); | ||||
| 2658 | @@ -122,12 +121,11 @@ | ||||
| 2659 | argvArray.append(RubyString.newStringShared(runtime, argv[i].getBytes())); | ||||
| 2660 | } | ||||
| 2661 | runtime.defineGlobalConstant("ARGV", argvArray); | ||||
| 2662 | - runtime.getGlobalVariables().defineReadonly("$*", new ValueAccessor(argvArray)); | ||||
| 2663 | + runtime.getGlobalVariables().defineReadonly("$*", new RuntimeVariableAccessor("$*", argvArray)); | ||||
| 2664 | |||||
| 2665 | - IAccessor d = new ValueAccessor(runtime.newString( | ||||
| 2666 | - runtime.getInstanceConfig().displayedFileName())); | ||||
| 2667 | - runtime.getGlobalVariables().define("$PROGRAM_NAME", d); | ||||
| 2668 | - runtime.getGlobalVariables().define("$0", d); | ||||
| 2669 | + RubyString fileName = runtime.newString(runtime.getInstanceConfig().displayedFileName()); | ||||
| 2670 | + runtime.getGlobalVariables().define("$PROGRAM_NAME", new RuntimeVariableAccessor("$PROGRAM_NAME", fileName)); | ||||
| 2671 | + runtime.getGlobalVariables().define("$0", new RuntimeVariableAccessor("$0", fileName)); | ||||
| 2672 | |||||
| 2673 | // Version information: | ||||
| 2674 | IRubyObject version = runtime.newString(Constants.RUBY_VERSION).freeze(context); | ||||
| 2675 | @@ -144,36 +142,36 @@ | ||||
| 2676 | runtime.defineGlobalConstant("VERSION", version); | ||||
| 2677 | runtime.defineGlobalConstant("RELEASE_DATE", release); | ||||
| 2678 | runtime.defineGlobalConstant("PLATFORM", platform); | ||||
| 2679 | - | ||||
| 2680 | + | ||||
| 2681 | IRubyObject jrubyVersion = runtime.newString(Constants.VERSION).freeze(context); | ||||
| 2682 | runtime.defineGlobalConstant("JRUBY_VERSION", jrubyVersion); | ||||
| 2683 | - | ||||
| 2684 | - GlobalVariable kcodeGV = new KCodeGlobalVariable(runtime, "$KCODE", runtime.newString("NONE")); | ||||
| 2685 | + | ||||
| 2686 | + GlobalVariable kcodeGV = new KCodeGlobalVariable("$KCODE", runtime.newString("NONE")); | ||||
| 2687 | runtime.defineVariable(kcodeGV); | ||||
| 2688 | runtime.defineVariable(new GlobalVariable.Copy(runtime, "$-K", kcodeGV)); | ||||
| 2689 | IRubyObject defaultRS = runtime.newString(runtime.getInstanceConfig().getRecordSeparator()).freeze(context); | ||||
| 2690 | - GlobalVariable rs = new StringGlobalVariable(runtime, "$/", defaultRS); | ||||
| 2691 | + GlobalVariable rs = new StringGlobalVariable("$/", defaultRS); | ||||
| 2692 | runtime.defineVariable(rs); | ||||
| 2693 | runtime.setRecordSeparatorVar(rs); | ||||
| 2694 | runtime.getGlobalVariables().setDefaultSeparator(defaultRS); | ||||
| 2695 | - runtime.defineVariable(new StringGlobalVariable(runtime, "$\\", runtime.getNil())); | ||||
| 2696 | - runtime.defineVariable(new StringGlobalVariable(runtime, "$,", runtime.getNil())); | ||||
| 2697 | + runtime.defineVariable(new StringGlobalVariable("$\\", runtime.getNil())); | ||||
| 2698 | + runtime.defineVariable(new StringGlobalVariable("$,", runtime.getNil())); | ||||
| 2699 | |||||
| 2700 | - runtime.defineVariable(new LineNumberGlobalVariable(runtime, "$.", RubyFixnum.one(runtime))); | ||||
| 2701 | - runtime.defineVariable(new LastlineGlobalVariable(runtime, "$_")); | ||||
| 2702 | - runtime.defineVariable(new LastExitStatusVariable(runtime, "$?")); | ||||
| 2703 | + runtime.defineVariable(new LineNumberGlobalVariable("$.", RubyFixnum.one(runtime))); | ||||
| 2704 | + runtime.defineVariable(new LastlineGlobalVariable("$_")); | ||||
| 2705 | + runtime.defineVariable(new LastExitStatusVariable("$?")); | ||||
| 2706 | |||||
| 2707 | - runtime.defineVariable(new ErrorInfoGlobalVariable(runtime, "$!", runtime.getNil())); | ||||
| 2708 | - runtime.defineVariable(new NonEffectiveGlobalVariable(runtime, "$=", runtime.getFalse())); | ||||
| 2709 | + runtime.defineVariable(new ErrorInfoGlobalVariable("$!", runtime.getNil())); | ||||
| 2710 | + runtime.defineVariable(new NonEffectiveGlobalVariable("$=", runtime.getFalse())); | ||||
| 2711 | |||||
| 2712 | if(runtime.getInstanceConfig().getInputFieldSeparator() == null) { | ||||
| 2713 | - runtime.defineVariable(new GlobalVariable(runtime, "$;", runtime.getNil())); | ||||
| 2714 | + runtime.defineVariable(new GlobalVariable("$;", runtime.getNil())); | ||||
| 2715 | } else { | ||||
| 2716 | - runtime.defineVariable(new GlobalVariable(runtime, "$;", RubyRegexp.newRegexp(runtime, runtime.getInstanceConfig().getInputFieldSeparator(), 0))); | ||||
| 2717 | + runtime.defineVariable(new GlobalVariable("$;", RubyRegexp.newRegexp(runtime, runtime.getInstanceConfig().getInputFieldSeparator(), 0))); | ||||
| 2718 | } | ||||
| 2719 | - | ||||
| 2720 | + | ||||
| 2721 | Boolean verbose = runtime.getInstanceConfig().getVerbose(); | ||||
| 2722 | - IRubyObject verboseValue = null; | ||||
| 2723 | + IRubyObject verboseValue; | ||||
| 2724 | if (verbose == null) { | ||||
| 2725 | verboseValue = runtime.getNil(); | ||||
| 2726 | } else if(verbose == Boolean.TRUE) { | ||||
| 2727 | @@ -181,68 +179,67 @@ | ||||
| 2728 | } else { | ||||
| 2729 | verboseValue = runtime.getFalse(); | ||||
| 2730 | } | ||||
| 2731 | - runtime.defineVariable(new VerboseGlobalVariable(runtime, "$VERBOSE", verboseValue)); | ||||
| 2732 | - | ||||
| 2733 | + runtime.defineVariable(new VerboseGlobalVariable("$VERBOSE", verboseValue)); | ||||
| 2734 | + | ||||
| 2735 | IRubyObject debug = runtime.newBoolean(runtime.getInstanceConfig().isDebug()); | ||||
| 2736 | - runtime.defineVariable(new DebugGlobalVariable(runtime, "$DEBUG", debug)); | ||||
| 2737 | - runtime.defineVariable(new DebugGlobalVariable(runtime, "$-d", debug)); | ||||
| 2738 | + runtime.defineVariable(new DebugGlobalVariable("$DEBUG", debug)); | ||||
| 2739 | + runtime.defineVariable(new DebugGlobalVariable("$-d", debug)); | ||||
| 2740 | |||||
| 2741 | - runtime.defineVariable(new SafeGlobalVariable(runtime, "$SAFE")); | ||||
| 2742 | + runtime.defineVariable(new SafeGlobalVariable("$SAFE")); | ||||
| 2743 | |||||
| 2744 | - runtime.defineVariable(new BacktraceGlobalVariable(runtime, "$@")); | ||||
| 2745 | + runtime.defineVariable(new BacktraceGlobalVariable("$@")); | ||||
| 2746 | |||||
| 2747 | IRubyObject stdin = new RubyIO(runtime, STDIO.IN); | ||||
| 2748 | IRubyObject stdout = new RubyIO(runtime, STDIO.OUT); | ||||
| 2749 | IRubyObject stderr = new RubyIO(runtime, STDIO.ERR); | ||||
| 2750 | |||||
| 2751 | - runtime.defineVariable(new InputGlobalVariable(runtime, "$stdin", stdin)); | ||||
| 2752 | + runtime.getGlobalVariables().define("$stdin", new RuntimeVariableAccessor("$stdin", stdin)); | ||||
| 2753 | |||||
| 2754 | - runtime.defineVariable(new OutputGlobalVariable(runtime, "$stdout", stdout)); | ||||
| 2755 | + runtime.getGlobalVariables().define("$stdout", new RuntimeOutputAccessor("$stdout", stdout)); | ||||
| 2756 | runtime.getGlobalVariables().alias("$>", "$stdout"); | ||||
| 2757 | runtime.getGlobalVariables().alias("$defout", "$stdout"); | ||||
| 2758 | |||||
| 2759 | - runtime.defineVariable(new OutputGlobalVariable(runtime, "$stderr", stderr)); | ||||
| 2760 | + runtime.getGlobalVariables().define("$stderr", new RuntimeOutputAccessor("$stderr", stderr)); | ||||
| 2761 | runtime.getGlobalVariables().alias("$deferr", "$stderr"); | ||||
| 2762 | |||||
| 2763 | runtime.defineGlobalConstant("STDIN", stdin); | ||||
| 2764 | runtime.defineGlobalConstant("STDOUT", stdout); | ||||
| 2765 | runtime.defineGlobalConstant("STDERR", stderr); | ||||
| 2766 | |||||
| 2767 | - runtime.defineVariable(new LoadedFeatures(runtime, "$\"")); | ||||
| 2768 | - runtime.defineVariable(new LoadedFeatures(runtime, "$LOADED_FEATURES")); | ||||
| 2769 | + runtime.defineVariable(new LoadedFeatures("$\"")); | ||||
| 2770 | + runtime.defineVariable(new LoadedFeatures("$LOADED_FEATURES")); | ||||
| 2771 | |||||
| 2772 | - runtime.defineVariable(new LoadPath(runtime, "$:")); | ||||
| 2773 | - runtime.defineVariable(new LoadPath(runtime, "$-I")); | ||||
| 2774 | - runtime.defineVariable(new LoadPath(runtime, "$LOAD_PATH")); | ||||
| 2775 | - | ||||
| 2776 | - runtime.defineVariable(new MatchMatchGlobalVariable(runtime, "$&")); | ||||
| 2777 | - runtime.defineVariable(new PreMatchGlobalVariable(runtime, "$`")); | ||||
| 2778 | - runtime.defineVariable(new PostMatchGlobalVariable(runtime, "$'")); | ||||
| 2779 | - runtime.defineVariable(new LastMatchGlobalVariable(runtime, "$+")); | ||||
| 2780 | - runtime.defineVariable(new BackRefGlobalVariable(runtime, "$~")); | ||||
| 2781 | + runtime.defineVariable(new LoadPath("$:")); | ||||
| 2782 | + runtime.defineVariable(new LoadPath("$-I")); | ||||
| 2783 | + runtime.defineVariable(new LoadPath("$LOAD_PATH")); | ||||
| 2784 | |||||
| 2785 | - // On platforms without a c-library accessable through JNA, getpid will return hashCode | ||||
| 2786 | + runtime.defineVariable(new MatchMatchGlobalVariable("$&")); | ||||
| 2787 | + runtime.defineVariable(new PreMatchGlobalVariable("$`")); | ||||
| 2788 | + runtime.defineVariable(new PostMatchGlobalVariable("$'")); | ||||
| 2789 | + runtime.defineVariable(new LastMatchGlobalVariable("$+")); | ||||
| 2790 | + runtime.defineVariable(new BackRefGlobalVariable("$~")); | ||||
| 2791 | + | ||||
| 2792 | + // On platforms without a c-library accessable through JNA, getpid will return hashCode | ||||
| 2793 | // as $$ used to. Using $$ to kill processes could take down many runtimes, but by basing | ||||
| 2794 | // $$ on getpid() where available, we have the same semantics as MRI. | ||||
| 2795 | - runtime.getGlobalVariables().defineReadonly("$$", new ValueAccessor(runtime.newFixnum(runtime.getPosix().getpid()))); | ||||
| 2796 | + RubyFixnum pid = runtime.newFixnum(runtime.getPosix().getpid()); | ||||
| 2797 | + runtime.getGlobalVariables().defineReadonly("$$", new RuntimeVariableAccessor("$$", pid)); | ||||
| 2798 | |||||
| 2799 | // after defn of $stderr as the call may produce warnings | ||||
| 2800 | defineGlobalEnvConstants(runtime); | ||||
| 2801 | - | ||||
| 2802 | - // Fixme: Do we need the check or does Main.java not call this...they should consolidate | ||||
| 2803 | - if (runtime.getGlobalVariables().get("$*").isNil()) { | ||||
| 2804 | - runtime.getGlobalVariables().defineReadonly("$*", new ValueAccessor(runtime.newArray())); | ||||
| 2805 | - } | ||||
| 2806 | - | ||||
| 2807 | - runtime.getGlobalVariables().defineReadonly("$-p", | ||||
| 2808 | - new ValueAccessor(runtime.getInstanceConfig().isAssumePrinting() ? runtime.getTrue() : runtime.getNil())); | ||||
| 2809 | - runtime.getGlobalVariables().defineReadonly("$-n", | ||||
| 2810 | - new ValueAccessor(runtime.getInstanceConfig().isAssumeLoop() ? runtime.getTrue() : runtime.getNil())); | ||||
| 2811 | - runtime.getGlobalVariables().defineReadonly("$-a", | ||||
| 2812 | - new ValueAccessor(runtime.getInstanceConfig().isSplit() ? runtime.getTrue() : runtime.getNil())); | ||||
| 2813 | - runtime.getGlobalVariables().defineReadonly("$-l", | ||||
| 2814 | - new ValueAccessor(runtime.getInstanceConfig().isProcessLineEnds() ? runtime.getTrue() : runtime.getNil())); | ||||
| 2815 | |||||
| 2816 | + IRubyObject assumePrinting = runtime.getInstanceConfig().isAssumePrinting() ? runtime.getTrue() : runtime.getNil(); | ||||
| 2817 | + runtime.getGlobalVariables().defineReadonly("$-p", new RuntimeVariableAccessor("$-p", assumePrinting)); | ||||
| 2818 | + | ||||
| 2819 | + IRubyObject assumeLoop = runtime.getInstanceConfig().isAssumeLoop() ? runtime.getTrue() : runtime.getNil(); | ||||
| 2820 | + runtime.getGlobalVariables().defineReadonly("$-n", new RuntimeVariableAccessor("$-n", assumeLoop)); | ||||
| 2821 | + | ||||
| 2822 | + IRubyObject split = runtime.getInstanceConfig().isSplit() ? runtime.getTrue() : runtime.getNil(); | ||||
| 2823 | + runtime.getGlobalVariables().defineReadonly("$-a", new RuntimeVariableAccessor("$-a", split)); | ||||
| 2824 | + | ||||
| 2825 | + IRubyObject processLineEnds = runtime.getInstanceConfig().isProcessLineEnds() ? runtime.getTrue() : runtime.getNil(); | ||||
| 2826 | + runtime.getGlobalVariables().defineReadonly("$-l", new RuntimeVariableAccessor("S-l", processLineEnds)); | ||||
| 2827 | + | ||||
| 2828 | // ARGF, $< object | ||||
| 2829 | RubyArgsFile.initArgsFile(runtime); | ||||
| 2830 | } | ||||
| 2831 | @@ -254,10 +251,10 @@ | ||||
| 2832 | try { | ||||
| 2833 | environmentVariableMap = environment.getEnvironmentVariableMap(runtime); | ||||
| 2834 | } catch (OSEnvironmentReaderExcepton e) { | ||||
| 2835 | - // If the environment variables are not accessible shouldn't terminate | ||||
| 2836 | + // If the environment variables are not accessible shouldn't terminate | ||||
| 2837 | runtime.getWarnings().warn(ID.MISCELLANEOUS, e.getMessage()); | ||||
| 2838 | } | ||||
| 2839 | - | ||||
| 2840 | + | ||||
| 2841 | if (environmentVariableMap == null) { | ||||
| 2842 | // if the environment variables can't be obtained, define an empty ENV | ||||
| 2843 | environmentVariableMap = new HashMap(); | ||||
| 2844 | @@ -272,103 +269,109 @@ | ||||
| 2845 | Map systemProps = environment.getSystemPropertiesMap(runtime); | ||||
| 2846 | runtime.defineGlobalConstant("ENV_JAVA", new StringOnlyRubyHash( | ||||
| 2847 | runtime, systemProps, runtime.getNil())); | ||||
| 2848 | - | ||||
| 2849 | + | ||||
| 2850 | } | ||||
| 2851 | |||||
| 2852 | + private static Ruby getRuntime() { | ||||
| 2853 | + return Ruby.getCurrentRuntime(); | ||||
| 2854 | + } | ||||
| 2855 | + | ||||
| 2856 | private static class NonEffectiveGlobalVariable extends GlobalVariable { | ||||
| 2857 | - public NonEffectiveGlobalVariable(Ruby runtime, String name, IRubyObject value) { | ||||
| 2858 | - super(runtime, name, value); | ||||
| 2859 | + public NonEffectiveGlobalVariable(String name, IRubyObject value) { | ||||
| 2860 | + super(name, value); | ||||
| 2861 | } | ||||
| 2862 | |||||
| 2863 | @Override | ||||
| 2864 | public IRubyObject set(IRubyObject value) { | ||||
| 2865 | - runtime.getWarnings().warn(ID.INEFFECTIVE_GLOBAL, "warning: variable " + name + " is no longer effective; ignored", name); | ||||
| 2866 | + getRuntime().getWarnings().warn(ID.INEFFECTIVE_GLOBAL, "warning: variable " + name + " is no longer effective; ignored", name); | ||||
| 2867 | return value; | ||||
| 2868 | } | ||||
| 2869 | |||||
| 2870 | + | ||||
| 2871 | @Override | ||||
| 2872 | public IRubyObject get() { | ||||
| 2873 | - runtime.getWarnings().warn(ID.INEFFECTIVE_GLOBAL, "warning: variable " + name + " is no longer effective", name); | ||||
| 2874 | - return runtime.getFalse(); | ||||
| 2875 | + getRuntime().getWarnings().warn(ID.INEFFECTIVE_GLOBAL, "warning: variable " + name + " is no longer effective", name); | ||||
| 2876 | + return getRuntime().getFalse(); | ||||
| 2877 | } | ||||
| 2878 | + | ||||
| 2879 | } | ||||
| 2880 | |||||
| 2881 | private static class LastExitStatusVariable extends GlobalVariable { | ||||
| 2882 | - public LastExitStatusVariable(Ruby runtime, String name) { | ||||
| 2883 | - super(runtime, name, runtime.getNil()); | ||||
| 2884 | + public LastExitStatusVariable(String name) { | ||||
| 2885 | + super(name, getRuntime().getNil()); | ||||
| 2886 | } | ||||
| 2887 | - | ||||
| 2888 | + | ||||
| 2889 | @Override | ||||
| 2890 | public IRubyObject get() { | ||||
| 2891 | - IRubyObject lastExitStatus = runtime.getCurrentContext().getLastExitStatus(); | ||||
| 2892 | - return lastExitStatus == null ? runtime.getNil() : lastExitStatus; | ||||
| 2893 | + IRubyObject lastExitStatus = getRuntime().getCurrentContext().getLastExitStatus(); | ||||
| 2894 | + return lastExitStatus == null ? getRuntime().getNil() : lastExitStatus; | ||||
| 2895 | } | ||||
| 2896 | - | ||||
| 2897 | + | ||||
| 2898 | @Override | ||||
| 2899 | public IRubyObject set(IRubyObject lastExitStatus) { | ||||
| 2900 | - runtime.getCurrentContext().setLastExitStatus(lastExitStatus); | ||||
| 2901 | - | ||||
| 2902 | + getRuntime().getCurrentContext().setLastExitStatus(lastExitStatus); | ||||
| 2903 | + | ||||
| 2904 | return lastExitStatus; | ||||
| 2905 | } | ||||
| 2906 | } | ||||
| 2907 | |||||
| 2908 | private static class MatchMatchGlobalVariable extends GlobalVariable { | ||||
| 2909 | - public MatchMatchGlobalVariable(Ruby runtime, String name) { | ||||
| 2910 | - super(runtime, name, runtime.getNil()); | ||||
| 2911 | + public MatchMatchGlobalVariable(String name) { | ||||
| 2912 | + super(name, getRuntime().getNil()); | ||||
| 2913 | } | ||||
| 2914 | - | ||||
| 2915 | + | ||||
| 2916 | @Override | ||||
| 2917 | public IRubyObject get() { | ||||
| 2918 | - return RubyRegexp.last_match(runtime.getCurrentContext().getCurrentFrame().getBackRef()); | ||||
| 2919 | + return RubyRegexp.last_match(getRuntime().getCurrentContext().getCurrentFrame().getBackRef()); | ||||
| 2920 | } | ||||
| 2921 | } | ||||
| 2922 | |||||
| 2923 | private static class PreMatchGlobalVariable extends GlobalVariable { | ||||
| 2924 | - public PreMatchGlobalVariable(Ruby runtime, String name) { | ||||
| 2925 | - super(runtime, name, runtime.getNil()); | ||||
| 2926 | + public PreMatchGlobalVariable(String name) { | ||||
| 2927 | + super(name, getRuntime().getNil()); | ||||
| 2928 | } | ||||
| 2929 | - | ||||
| 2930 | + | ||||
| 2931 | @Override | ||||
| 2932 | public IRubyObject get() { | ||||
| 2933 | - return RubyRegexp.match_pre(runtime.getCurrentContext().getCurrentFrame().getBackRef()); | ||||
| 2934 | + return RubyRegexp.match_pre(getRuntime().getCurrentContext().getCurrentFrame().getBackRef()); | ||||
| 2935 | } | ||||
| 2936 | } | ||||
| 2937 | |||||
| 2938 | private static class PostMatchGlobalVariable extends GlobalVariable { | ||||
| 2939 | - public PostMatchGlobalVariable(Ruby runtime, String name) { | ||||
| 2940 | - super(runtime, name, runtime.getNil()); | ||||
| 2941 | + public PostMatchGlobalVariable(String name) { | ||||
| 2942 | + super(name, getRuntime().getNil()); | ||||
| 2943 | } | ||||
| 2944 | - | ||||
| 2945 | + | ||||
| 2946 | @Override | ||||
| 2947 | public IRubyObject get() { | ||||
| 2948 | - return RubyRegexp.match_post(runtime.getCurrentContext().getCurrentFrame().getBackRef()); | ||||
| 2949 | + return RubyRegexp.match_post(getRuntime().getCurrentContext().getCurrentFrame().getBackRef()); | ||||
| 2950 | } | ||||
| 2951 | } | ||||
| 2952 | |||||
| 2953 | private static class LastMatchGlobalVariable extends GlobalVariable { | ||||
| 2954 | - public LastMatchGlobalVariable(Ruby runtime, String name) { | ||||
| 2955 | - super(runtime, name, runtime.getNil()); | ||||
| 2956 | + public LastMatchGlobalVariable(String name) { | ||||
| 2957 | + super(name, getRuntime().getNil()); | ||||
| 2958 | } | ||||
| 2959 | - | ||||
| 2960 | + | ||||
| 2961 | @Override | ||||
| 2962 | public IRubyObject get() { | ||||
| 2963 | - return RubyRegexp.match_last(runtime.getCurrentContext().getCurrentFrame().getBackRef()); | ||||
| 2964 | + return RubyRegexp.match_last(getRuntime().getCurrentContext().getCurrentFrame().getBackRef()); | ||||
| 2965 | } | ||||
| 2966 | } | ||||
| 2967 | |||||
| 2968 | private static class BackRefGlobalVariable extends GlobalVariable { | ||||
| 2969 | - public BackRefGlobalVariable(Ruby runtime, String name) { | ||||
| 2970 | - super(runtime, name, runtime.getNil()); | ||||
| 2971 | + public BackRefGlobalVariable(String name) { | ||||
| 2972 | + super(name, getRuntime().getNil()); | ||||
| 2973 | } | ||||
| 2974 | - | ||||
| 2975 | + | ||||
| 2976 | @Override | ||||
| 2977 | public IRubyObject get() { | ||||
| 2978 | - return RuntimeHelpers.getBackref(runtime, runtime.getCurrentContext()); | ||||
| 2979 | + return RuntimeHelpers.getBackref(getRuntime(), getRuntime().getCurrentContext()); | ||||
| 2980 | } | ||||
| 2981 | |||||
| 2982 | @Override | ||||
| 2983 | public IRubyObject set(IRubyObject value) { | ||||
| 2984 | - RuntimeHelpers.setBackref(runtime, runtime.getCurrentContext(), value); | ||||
| 2985 | + RuntimeHelpers.setBackref(getRuntime(), getRuntime().getCurrentContext(), value); | ||||
| 2986 | return value; | ||||
| 2987 | } | ||||
| 2988 | } | ||||
| 2989 | @@ -376,113 +379,113 @@ | ||||
| 2990 | // Accessor methods. | ||||
| 2991 | |||||
| 2992 | private static class LineNumberGlobalVariable extends GlobalVariable { | ||||
| 2993 | - public LineNumberGlobalVariable(Ruby runtime, String name, RubyFixnum value) { | ||||
| 2994 | - super(runtime, name, value); | ||||
| 2995 | + public LineNumberGlobalVariable(String name, RubyFixnum value) { | ||||
| 2996 | + super(name, value); | ||||
| 2997 | } | ||||
| 2998 | |||||
| 2999 | @Override | ||||
| 3000 | public IRubyObject set(IRubyObject value) { | ||||
| 3001 | - RubyArgsFile.setCurrentLineNumber(runtime.getGlobalVariables().get("$<"),RubyNumeric.fix2int(value)); | ||||
| 3002 | + RubyArgsFile.setCurrentLineNumber(getRuntime().getGlobalVariables().get("$<"),RubyNumeric.fix2int(value)); | ||||
| 3003 | return super.set(value); | ||||
| 3004 | } | ||||
| 3005 | } | ||||
| 3006 | |||||
| 3007 | private static class ErrorInfoGlobalVariable extends GlobalVariable { | ||||
| 3008 | - public ErrorInfoGlobalVariable(Ruby runtime, String name, IRubyObject value) { | ||||
| 3009 | - super(runtime, name, null); | ||||
| 3010 | + public ErrorInfoGlobalVariable(String name, IRubyObject value) { | ||||
| 3011 | + super(name, null); | ||||
| 3012 | set(value); | ||||
| 3013 | } | ||||
| 3014 | |||||
| 3015 | @Override | ||||
| 3016 | public IRubyObject set(IRubyObject value) { | ||||
| 3017 | if (!value.isNil() && | ||||
| 3018 | - !runtime.getException().isInstance(value) && | ||||
| 3019 | + !getRuntime().getException().isInstance(value) && | ||||
| 3020 | !(JavaUtil.isJavaObject(value) && JavaUtil.unwrapJavaObject(value) instanceof Exception)) { | ||||
| 3021 | - throw runtime.newTypeError("assigning non-exception to $!"); | ||||
| 3022 | + throw getRuntime().newTypeError("assigning non-exception to $!"); | ||||
| 3023 | } | ||||
| 3024 | - | ||||
| 3025 | - return runtime.getCurrentContext().setErrorInfo(value); | ||||
| 3026 | + | ||||
| 3027 | + return getRuntime().getCurrentContext().setErrorInfo(value); | ||||
| 3028 | } | ||||
| 3029 | |||||
| 3030 | @Override | ||||
| 3031 | public IRubyObject get() { | ||||
| 3032 | - return runtime.getCurrentContext().getErrorInfo(); | ||||
| 3033 | + return getRuntime().getCurrentContext().getErrorInfo(); | ||||
| 3034 | } | ||||
| 3035 | } | ||||
| 3036 | |||||
| 3037 | // FIXME: move out of this class! | ||||
| 3038 | public static class StringGlobalVariable extends GlobalVariable { | ||||
| 3039 | - public StringGlobalVariable(Ruby runtime, String name, IRubyObject value) { | ||||
| 3040 | - super(runtime, name, value); | ||||
| 3041 | + public StringGlobalVariable(String name, IRubyObject value) { | ||||
| 3042 | + super(name, value); | ||||
| 3043 | } | ||||
| 3044 | |||||
| 3045 | @Override | ||||
| 3046 | public IRubyObject set(IRubyObject value) { | ||||
| 3047 | if (!value.isNil() && ! (value instanceof RubyString)) { | ||||
| 3048 | - throw runtime.newTypeError("value of " + name() + " must be a String"); | ||||
| 3049 | + throw getRuntime().newTypeError("value of " + name() + " must be a String"); | ||||
| 3050 | } | ||||
| 3051 | return super.set(value); | ||||
| 3052 | } | ||||
| 3053 | } | ||||
| 3054 | |||||
| 3055 | public static class KCodeGlobalVariable extends GlobalVariable { | ||||
| 3056 | - public KCodeGlobalVariable(Ruby runtime, String name, IRubyObject value) { | ||||
| 3057 | - super(runtime, name, value); | ||||
| 3058 | + public KCodeGlobalVariable(String name, IRubyObject value) { | ||||
| 3059 | + super(name, value); | ||||
| 3060 | } | ||||
| 3061 | |||||
| 3062 | @Override | ||||
| 3063 | public IRubyObject get() { | ||||
| 3064 | - return runtime.getKCode().kcode(runtime); | ||||
| 3065 | + return getRuntime().getKCode().kcode(getRuntime()); | ||||
| 3066 | } | ||||
| 3067 | |||||
| 3068 | @Override | ||||
| 3069 | public IRubyObject set(IRubyObject value) { | ||||
| 3070 | - runtime.setKCode(KCode.create(runtime, value.convertToString().toString())); | ||||
| 3071 | + getRuntime().setKCode(KCode.create(getRuntime(), value.convertToString().toString())); | ||||
| 3072 | return value; | ||||
| 3073 | } | ||||
| 3074 | } | ||||
| 3075 | |||||
| 3076 | private static class SafeGlobalVariable extends GlobalVariable { | ||||
| 3077 | - public SafeGlobalVariable(Ruby runtime, String name) { | ||||
| 3078 | - super(runtime, name, null); | ||||
| 3079 | + public SafeGlobalVariable(String name) { | ||||
| 3080 | + super(name, null); | ||||
| 3081 | } | ||||
| 3082 | |||||
| 3083 | @Override | ||||
| 3084 | public IRubyObject get() { | ||||
| 3085 | - return runtime.newFixnum(runtime.getSafeLevel()); | ||||
| 3086 | + return getRuntime().newFixnum(getRuntime().getSafeLevel()); | ||||
| 3087 | } | ||||
| 3088 | |||||
| 3089 | @Override | ||||
| 3090 | public IRubyObject set(IRubyObject value) { | ||||
| 3091 | // int level = RubyNumeric.fix2int(value); | ||||
| 3092 | -// if (level < runtime.getSafeLevel()) { | ||||
| 3093 | -// throw runtime.newSecurityError("tried to downgrade safe level from " + | ||||
| 3094 | -// runtime.getSafeLevel() + " to " + level); | ||||
| 3095 | +// if (level < getRuntime().getSafeLevel()) { | ||||
| 3096 | +// throw getRuntime().newSecurityError("tried to downgrade safe level from " + | ||||
| 3097 | +// getRuntime().getSafeLevel() + " to " + level); | ||||
| 3098 | // } | ||||
| 3099 | -// runtime.setSafeLevel(level); | ||||
| 3100 | +// getRuntime().setSafeLevel(level); | ||||
| 3101 | // thread.setSafeLevel(level); | ||||
| 3102 | - runtime.getWarnings().warn(ID.SAFE_NOT_SUPPORTED, "SAFE levels are not supported in JRuby"); | ||||
| 3103 | - return RubyFixnum.newFixnum(runtime, runtime.getSafeLevel()); | ||||
| 3104 | + getRuntime().getWarnings().warn(ID.SAFE_NOT_SUPPORTED, "SAFE levels are not supported in JRuby"); | ||||
| 3105 | + return RubyFixnum.newFixnum(getRuntime(), getRuntime().getSafeLevel()); | ||||
| 3106 | } | ||||
| 3107 | } | ||||
| 3108 | |||||
| 3109 | private static class VerboseGlobalVariable extends GlobalVariable { | ||||
| 3110 | - public VerboseGlobalVariable(Ruby runtime, String name, IRubyObject initialValue) { | ||||
| 3111 | - super(runtime, name, initialValue); | ||||
| 3112 | + public VerboseGlobalVariable(String name, IRubyObject initialValue) { | ||||
| 3113 | + super(name, initialValue); | ||||
| 3114 | set(initialValue); | ||||
| 3115 | } | ||||
| 3116 | - | ||||
| 3117 | + | ||||
| 3118 | @Override | ||||
| 3119 | public IRubyObject get() { | ||||
| 3120 | - return runtime.getVerbose(); | ||||
| 3121 | + return getRuntime().getVerbose(); | ||||
| 3122 | } | ||||
| 3123 | |||||
| 3124 | @Override | ||||
| 3125 | public IRubyObject set(IRubyObject newValue) { | ||||
| 3126 | if (newValue.isNil()) { | ||||
| 3127 | - runtime.setVerbose(newValue); | ||||
| 3128 | + getRuntime().setVerbose(newValue); | ||||
| 3129 | } else { | ||||
| 3130 | - runtime.setVerbose(runtime.newBoolean(newValue.isTrue())); | ||||
| 3131 | + getRuntime().setVerbose(getRuntime().newBoolean(newValue.isTrue())); | ||||
| 3132 | } | ||||
| 3133 | |||||
| 3134 | return newValue; | ||||
| 3135 | @@ -490,22 +493,22 @@ | ||||
| 3136 | } | ||||
| 3137 | |||||
| 3138 | private static class DebugGlobalVariable extends GlobalVariable { | ||||
| 3139 | - public DebugGlobalVariable(Ruby runtime, String name, IRubyObject initialValue) { | ||||
| 3140 | - super(runtime, name, initialValue); | ||||
| 3141 | + public DebugGlobalVariable(String name, IRubyObject initialValue) { | ||||
| 3142 | + super(name, initialValue); | ||||
| 3143 | set(initialValue); | ||||
| 3144 | } | ||||
| 3145 | |||||
| 3146 | @Override | ||||
| 3147 | public IRubyObject get() { | ||||
| 3148 | - return runtime.getDebug(); | ||||
| 3149 | + return getRuntime().getDebug(); | ||||
| 3150 | } | ||||
| 3151 | |||||
| 3152 | @Override | ||||
| 3153 | public IRubyObject set(IRubyObject newValue) { | ||||
| 3154 | if (newValue.isNil()) { | ||||
| 3155 | - runtime.setDebug(newValue); | ||||
| 3156 | + getRuntime().setDebug(newValue); | ||||
| 3157 | } else { | ||||
| 3158 | - runtime.setDebug(runtime.newBoolean(newValue.isTrue())); | ||||
| 3159 | + getRuntime().setDebug(getRuntime().newBoolean(newValue.isTrue())); | ||||
| 3160 | } | ||||
| 3161 | |||||
| 3162 | return newValue; | ||||
| 3163 | @@ -513,115 +516,103 @@ | ||||
| 3164 | } | ||||
| 3165 | |||||
| 3166 | private static class BacktraceGlobalVariable extends GlobalVariable { | ||||
| 3167 | - public BacktraceGlobalVariable(Ruby runtime, String name) { | ||||
| 3168 | - super(runtime, name, null); | ||||
| 3169 | + public BacktraceGlobalVariable(String name) { | ||||
| 3170 | + super(name, null); | ||||
| 3171 | } | ||||
| 3172 | |||||
| 3173 | @Override | ||||
| 3174 | public IRubyObject get() { | ||||
| 3175 | - IRubyObject errorInfo = runtime.getGlobalVariables().get("$!"); | ||||
| 3176 | - IRubyObject backtrace = errorInfo.isNil() ? runtime.getNil() : errorInfo.callMethod(errorInfo.getRuntime().getCurrentContext(), "backtrace"); | ||||
| 3177 | + IRubyObject errorInfo = getRuntime().getGlobalVariables().get("$!"); | ||||
| 3178 | + IRubyObject backtrace = errorInfo.isNil() ? getRuntime().getNil() : errorInfo.callMethod(errorInfo.getRuntime().getCurrentContext(), "backtrace"); | ||||
| 3179 | //$@ returns nil if $!.backtrace is not an array | ||||
| 3180 | if (!(backtrace instanceof RubyArray)) { | ||||
| 3181 | - backtrace = runtime.getNil(); | ||||
| 3182 | + backtrace = getRuntime().getNil(); | ||||
| 3183 | } | ||||
| 3184 | return backtrace; | ||||
| 3185 | } | ||||
| 3186 | |||||
| 3187 | @Override | ||||
| 3188 | public IRubyObject set(IRubyObject value) { | ||||
| 3189 | - if (runtime.getGlobalVariables().get("$!").isNil()) { | ||||
| 3190 | - throw runtime.newArgumentError("$! not set."); | ||||
| 3191 | + if (getRuntime().getGlobalVariables().get("$!").isNil()) { | ||||
| 3192 | + throw getRuntime().newArgumentError("$! not set."); | ||||
| 3193 | } | ||||
| 3194 | - runtime.getGlobalVariables().get("$!").callMethod(value.getRuntime().getCurrentContext(), "set_backtrace", value); | ||||
| 3195 | + getRuntime().getGlobalVariables().get("$!").callMethod(value.getRuntime().getCurrentContext(), "set_backtrace", value); | ||||
| 3196 | return value; | ||||
| 3197 | } | ||||
| 3198 | } | ||||
| 3199 | |||||
| 3200 | private static class LastlineGlobalVariable extends GlobalVariable { | ||||
| 3201 | - public LastlineGlobalVariable(Ruby runtime, String name) { | ||||
| 3202 | - super(runtime, name, null); | ||||
| 3203 | + public LastlineGlobalVariable(String name) { | ||||
| 3204 | + super(name, null); | ||||
| 3205 | } | ||||
| 3206 | |||||
| 3207 | @Override | ||||
| 3208 | public IRubyObject get() { | ||||
| 3209 | - return RuntimeHelpers.getLastLine(runtime, runtime.getCurrentContext()); | ||||
| 3210 | + return RuntimeHelpers.getLastLine(getRuntime(), getRuntime().getCurrentContext()); | ||||
| 3211 | } | ||||
| 3212 | |||||
| 3213 | @Override | ||||
| 3214 | public IRubyObject set(IRubyObject value) { | ||||
| 3215 | - RuntimeHelpers.setLastLine(runtime, runtime.getCurrentContext(), value); | ||||
| 3216 | + RuntimeHelpers.setLastLine(getRuntime(), getRuntime().getCurrentContext(), value); | ||||
| 3217 | return value; | ||||
| 3218 | } | ||||
| 3219 | } | ||||
| 3220 | |||||
| 3221 | - private static class InputGlobalVariable extends GlobalVariable { | ||||
| 3222 | - public InputGlobalVariable(Ruby runtime, String name, IRubyObject value) { | ||||
| 3223 | - super(runtime, name, value); | ||||
| 3224 | - } | ||||
| 3225 | + private static class RuntimeOutputAccessor extends RuntimeVariableAccessor { | ||||
| 3226 | + private final String name; | ||||
| 3227 | |||||
| 3228 | - @Override | ||||
| 3229 | - public IRubyObject set(IRubyObject value) { | ||||
| 3230 | - if (value == get()) { | ||||
| 3231 | - return value; | ||||
| 3232 | - } | ||||
| 3233 | - | ||||
| 3234 | - return super.set(value); | ||||
| 3235 | + public RuntimeOutputAccessor(String name, IRubyObject value) { | ||||
| 3236 | + super(name, value); | ||||
| 3237 | + this.name = name; | ||||
| 3238 | } | ||||
| 3239 | - } | ||||
| 3240 | |||||
| 3241 | - private static class OutputGlobalVariable extends GlobalVariable { | ||||
| 3242 | - public OutputGlobalVariable(Ruby runtime, String name, IRubyObject value) { | ||||
| 3243 | - super(runtime, name, value); | ||||
| 3244 | - } | ||||
| 3245 | - | ||||
| 3246 | @Override | ||||
| 3247 | - public IRubyObject set(IRubyObject value) { | ||||
| 3248 | - if (value == get()) { | ||||
| 3249 | - return value; | ||||
| 3250 | + public IRubyObject setValue(IRubyObject newValue) { | ||||
| 3251 | + if (newValue == getValue()) { | ||||
| 3252 | + return newValue; | ||||
| 3253 | } | ||||
| 3254 | - if (value instanceof RubyIO) { | ||||
| 3255 | - RubyIO io = (RubyIO)value; | ||||
| 3256 | - | ||||
| 3257 | + if (newValue instanceof RubyIO) { | ||||
| 3258 | + RubyIO io = (RubyIO)newValue; | ||||
| 3259 | + | ||||
| 3260 | // HACK: in order to have stdout/err act like ttys and flush always, | ||||
| 3261 | // we set anything assigned to stdout/stderr to sync | ||||
| 3262 | io.getHandler().setSync(true); | ||||
| 3263 | } | ||||
| 3264 | |||||
| 3265 | - if (!value.respondsTo("write")) { | ||||
| 3266 | - throw runtime.newTypeError(name() + " must have write method, " + | ||||
| 3267 | - value.getType().getName() + " given"); | ||||
| 3268 | + if (!newValue.respondsTo("write")) { | ||||
| 3269 | + throw getRuntime().newTypeError(name + " must have write method, " + | ||||
| 3270 | + newValue.getType().getName() + " given"); | ||||
| 3271 | } | ||||
| 3272 | |||||
| 3273 | - return super.set(value); | ||||
| 3274 | + return super.setValue(newValue); | ||||
| 3275 | } | ||||
| 3276 | } | ||||
| 3277 | |||||
| 3278 | private static class LoadPath extends ReadonlyGlobalVariable { | ||||
| 3279 | - public LoadPath(Ruby runtime, String name) { | ||||
| 3280 | - super(runtime, name, null); | ||||
| 3281 | + public LoadPath(String name) { | ||||
| 3282 | + super(name, null); | ||||
| 3283 | } | ||||
| 3284 | - | ||||
| 3285 | + | ||||
| 3286 | /** | ||||
| 3287 | * @see org.jruby.runtime.GlobalVariable#get() | ||||
| 3288 | */ | ||||
| 3289 | @Override | ||||
| 3290 | public IRubyObject get() { | ||||
| 3291 | - return runtime.getLoadService().getLoadPath(); | ||||
| 3292 | + return getRuntime().getLoadService().getLoadPath(); | ||||
| 3293 | } | ||||
| 3294 | } | ||||
| 3295 | |||||
| 3296 | private static class LoadedFeatures extends ReadonlyGlobalVariable { | ||||
| 3297 | - public LoadedFeatures(Ruby runtime, String name) { | ||||
| 3298 | - super(runtime, name, null); | ||||
| 3299 | + public LoadedFeatures(String name) { | ||||
| 3300 | + super(name, null); | ||||
| 3301 | } | ||||
| 3302 | - | ||||
| 3303 | + | ||||
| 3304 | /** | ||||
| 3305 | * @see org.jruby.runtime.GlobalVariable#get() | ||||
| 3306 | */ | ||||
| 3307 | @Override | ||||
| 3308 | public IRubyObject get() { | ||||
| 3309 | - return runtime.getLoadService().getLoadedFeatures(); | ||||
| 3310 | + return getRuntime().getLoadService().getLoadedFeatures(); | ||||
| 3311 | } | ||||
| 3312 | } | ||||
| 3313 | } | ||||
| 3314 | Index: src/org/jruby/RubyClass.java | ||||
| 3315 | =================================================================== | ||||
| 3316 | --- src/org/jruby/RubyClass.java (revision 8091) | ||||
| 3317 | +++ src/org/jruby/RubyClass.java (working copy) | ||||
| 3318 | @@ -54,6 +54,8 @@ | ||||
| 3319 | import org.jruby.runtime.marshal.MarshalStream; | ||||
| 3320 | import org.jruby.runtime.marshal.UnmarshalStream; | ||||
| 3321 | import org.jruby.util.collections.WeakHashSet; | ||||
| 3322 | +import org.jruby.util.RuntimeContainer; | ||||
| 3323 | +import org.jruby.util.JRubyClassLoader; | ||||
| 3324 | |||||
| 3325 | /** | ||||
| 3326 | * | ||||
| 3327 | @@ -74,7 +76,7 @@ | ||||
| 3328 | |||||
| 3329 | private CallSite[] extraCallSites; | ||||
| 3330 | |||||
| 3331 | - public static void createClassClass(Ruby runtime, RubyClass classClass) { | ||||
| 3332 | + public static void createClassClass(RubyClass classClass) { | ||||
| 3333 | classClass.index = ClassIndex.CLASS; | ||||
| 3334 | classClass.kindOf = new RubyModule.KindOf() { | ||||
| 3335 | @Override | ||||
| 3336 | @@ -116,9 +118,9 @@ | ||||
| 3337 | |||||
| 3338 | @JRubyMethod(name = "allocate") | ||||
| 3339 | public IRubyObject allocate() { | ||||
| 3340 | - if (superClass == null) throw runtime.newTypeError("can't instantiate uninitialized class"); | ||||
| 3341 | - IRubyObject obj = allocator.allocate(runtime, this); | ||||
| 3342 | - if (obj.getMetaClass().getRealClass() != getRealClass()) throw runtime.newTypeError("wrong instance allocation"); | ||||
| 3343 | + if (superClass == null) throw getRuntime().newTypeError("can't instantiate uninitialized class"); | ||||
| 3344 | + IRubyObject obj = allocator.allocate(getRuntime(), this); | ||||
| 3345 | + if (obj.getMetaClass().getRealClass() != getRealClass()) throw getRuntime().newTypeError("wrong instance allocation"); | ||||
| 3346 | return obj; | ||||
| 3347 | } | ||||
| 3348 | |||||
| 3349 | @@ -171,7 +173,6 @@ | ||||
| 3350 | return obj; | ||||
| 3351 | } | ||||
| 3352 | |||||
| 3353 | - private final Ruby runtime; | ||||
| 3354 | private ObjectAllocator allocator; // the default allocator | ||||
| 3355 | protected ObjectMarshal marshal; | ||||
| 3356 | private Set<RubyClass> subclasses; | ||||
| 3357 | @@ -182,7 +183,6 @@ | ||||
| 3358 | */ | ||||
| 3359 | protected RubyClass(Ruby runtime, RubyClass superClass, boolean objectSpace) { | ||||
| 3360 | super(runtime, runtime.getClassClass(), objectSpace); | ||||
| 3361 | - this.runtime = runtime; | ||||
| 3362 | this.superClass = superClass; // this is the only case it might be null here (in MetaClass construction) | ||||
| 3363 | } | ||||
| 3364 | |||||
| 3365 | @@ -192,7 +192,6 @@ | ||||
| 3366 | */ | ||||
| 3367 | protected RubyClass(Ruby runtime, RubyClass superClass, Generation generation, boolean objectSpace) { | ||||
| 3368 | super(runtime, runtime.getClassClass(), generation, objectSpace); | ||||
| 3369 | - this.runtime = runtime; | ||||
| 3370 | this.superClass = superClass; // this is the only case it might be null here (in MetaClass construction) | ||||
| 3371 | } | ||||
| 3372 | |||||
| 3373 | @@ -201,7 +200,6 @@ | ||||
| 3374 | */ | ||||
| 3375 | protected RubyClass(Ruby runtime) { | ||||
| 3376 | super(runtime, runtime.getClassClass()); | ||||
| 3377 | - this.runtime = runtime; | ||||
| 3378 | index = ClassIndex.CLASS; | ||||
| 3379 | } | ||||
| 3380 | |||||
| 3381 | @@ -624,7 +622,7 @@ | ||||
| 3382 | @JRubyMethod(name = "initialize_copy", required = 1, visibility = Visibility.PRIVATE) | ||||
| 3383 | @Override | ||||
| 3384 | public IRubyObject initialize_copy(IRubyObject original){ | ||||
| 3385 | - if (superClass != null) throw runtime.newTypeError("already initialized class"); | ||||
| 3386 | + if (superClass != null) throw getRuntime().newTypeError("already initialized class"); | ||||
| 3387 | if (original instanceof MetaClass) throw getRuntime().newTypeError("can't copy singleton class"); | ||||
| 3388 | |||||
| 3389 | super.initialize_copy(original); | ||||
| 3390 | @@ -675,7 +673,7 @@ | ||||
| 3391 | } | ||||
| 3392 | |||||
| 3393 | public Ruby getClassRuntime() { | ||||
| 3394 | - return runtime; | ||||
| 3395 | + return Ruby.getCurrentRuntime(); | ||||
| 3396 | } | ||||
| 3397 | |||||
| 3398 | public RubyClass getRealClass() { | ||||
| 3399 | Index: src/org/jruby/RubyIO.java | ||||
| 3400 | =================================================================== | ||||
| 3401 | --- src/org/jruby/RubyIO.java (revision 8091) | ||||
| 3402 | +++ src/org/jruby/RubyIO.java (working copy) | ||||
| 3403 | @@ -85,22 +85,22 @@ | ||||
| 3404 | import static org.jruby.RubyEnumerator.enumeratorize; | ||||
| 3405 | |||||
| 3406 | /** | ||||
| 3407 | - * | ||||
| 3408 | + * | ||||
| 3409 | * @author jpetersen | ||||
| 3410 | */ | ||||
| 3411 | @JRubyClass(name="IO", include="Enumerable") | ||||
| 3412 | public class RubyIO extends RubyObject { | ||||
| 3413 | protected OpenFile openFile; | ||||
| 3414 | protected List<RubyThread> blockingThreads; | ||||
| 3415 | - | ||||
| 3416 | + | ||||
| 3417 | public void registerDescriptor(ChannelDescriptor descriptor) { | ||||
| 3418 | getRuntime().getDescriptors().put(new Integer(descriptor.getFileno()), new WeakReference<ChannelDescriptor>(descriptor)); | ||||
| 3419 | } | ||||
| 3420 | - | ||||
| 3421 | + | ||||
| 3422 | public void unregisterDescriptor(int aFileno) { | ||||
| 3423 | getRuntime().getDescriptors().remove(new Integer(aFileno)); | ||||
| 3424 | } | ||||
| 3425 | - | ||||
| 3426 | + | ||||
| 3427 | public ChannelDescriptor getDescriptorByFileno(int aFileno) { | ||||
| 3428 | Reference<ChannelDescriptor> reference = getRuntime().getDescriptors().get(new Integer(aFileno)); | ||||
| 3429 | if (reference == null) { | ||||
| 3430 | @@ -108,10 +108,10 @@ | ||||
| 3431 | } | ||||
| 3432 | return reference.get(); | ||||
| 3433 | } | ||||
| 3434 | - | ||||
| 3435 | + | ||||
| 3436 | // FIXME can't use static; would interfere with other runtimes in the same JVM | ||||
| 3437 | protected static AtomicInteger filenoIndex = new AtomicInteger(2); | ||||
| 3438 | - | ||||
| 3439 | + | ||||
| 3440 | public static int getNewFileno() { | ||||
| 3441 | return filenoIndex.incrementAndGet(); | ||||
| 3442 | } | ||||
| 3443 | @@ -120,77 +120,77 @@ | ||||
| 3444 | // It allows this object to be created without a IOHandler. | ||||
| 3445 | public RubyIO(Ruby runtime, RubyClass type) { | ||||
| 3446 | super(runtime, type); | ||||
| 3447 | - | ||||
| 3448 | + | ||||
| 3449 | openFile = new OpenFile(); | ||||
| 3450 | } | ||||
| 3451 | |||||
| 3452 | public RubyIO(Ruby runtime, OutputStream outputStream) { | ||||
| 3453 | super(runtime, runtime.getIO()); | ||||
| 3454 | - | ||||
| 3455 | - // We only want IO objects with valid streams (better to error now). | ||||
| 3456 | + | ||||
| 3457 | + // We only want IO objects with valid streams (better to error now). | ||||
| 3458 | if (outputStream == null) { | ||||
| 3459 | throw runtime.newRuntimeError("Opening null stream"); | ||||
| 3460 | } | ||||
| 3461 | - | ||||
| 3462 | + | ||||
| 3463 | openFile = new OpenFile(); | ||||
| 3464 | - | ||||
| 3465 | + | ||||
| 3466 | try { | ||||
| 3467 | - openFile.setMainStream(new ChannelStream(runtime, new ChannelDescriptor(Channels.newChannel(outputStream), getNewFileno(), new FileDescriptor()))); | ||||
| 3468 | + openFile.setMainStream(new ChannelStream(new ChannelDescriptor(Channels.newChannel(outputStream), getNewFileno(), new FileDescriptor()))); | ||||
| 3469 | } catch (InvalidValueException e) { | ||||
| 3470 | throw getRuntime().newErrnoEINVALError(); | ||||
| 3471 | } | ||||
| 3472 | - | ||||
| 3473 | + | ||||
| 3474 | openFile.setMode(OpenFile.WRITABLE | OpenFile.APPEND); | ||||
| 3475 | - | ||||
| 3476 | + | ||||
| 3477 | registerDescriptor(openFile.getMainStream().getDescriptor()); | ||||
| 3478 | } | ||||
| 3479 | - | ||||
| 3480 | + | ||||
| 3481 | public RubyIO(Ruby runtime, InputStream inputStream) { | ||||
| 3482 | super(runtime, runtime.getIO()); | ||||
| 3483 | - | ||||
| 3484 | + | ||||
| 3485 | if (inputStream == null) { | ||||
| 3486 | throw runtime.newRuntimeError("Opening null stream"); | ||||
| 3487 | } | ||||
| 3488 | - | ||||
| 3489 | + | ||||
| 3490 | openFile = new OpenFile(); | ||||
| 3491 | - | ||||
| 3492 | + | ||||
| 3493 | try { | ||||
| 3494 | - openFile.setMainStream(new ChannelStream(runtime, new ChannelDescriptor(Channels.newChannel(inputStream), getNewFileno(), new FileDescriptor()))); | ||||
| 3495 | + openFile.setMainStream(new ChannelStream(new ChannelDescriptor(Channels.newChannel(inputStream), getNewFileno(), new FileDescriptor()))); | ||||
| 3496 | } catch (InvalidValueException e) { | ||||
| 3497 | throw getRuntime().newErrnoEINVALError(); | ||||
| 3498 | } | ||||
| 3499 | - | ||||
| 3500 | + | ||||
| 3501 | openFile.setMode(OpenFile.READABLE); | ||||
| 3502 | - | ||||
| 3503 | + | ||||
| 3504 | registerDescriptor(openFile.getMainStream().getDescriptor()); | ||||
| 3505 | } | ||||
| 3506 | - | ||||
| 3507 | + | ||||
| 3508 | public RubyIO(Ruby runtime, Channel channel) { | ||||
| 3509 | super(runtime, runtime.getIO()); | ||||
| 3510 | - | ||||
| 3511 | - // We only want IO objects with valid streams (better to error now). | ||||
| 3512 | + | ||||
| 3513 | + // We only want IO objects with valid streams (better to error now). | ||||
| 3514 | if (channel == null) { | ||||
| 3515 | throw runtime.newRuntimeError("Opening null channelpo"); | ||||
| 3516 | } | ||||
| 3517 | - | ||||
| 3518 | + | ||||
| 3519 | openFile = new OpenFile(); | ||||
| 3520 | - | ||||
| 3521 | + | ||||
| 3522 | try { | ||||
| 3523 | - openFile.setMainStream(new ChannelStream(runtime, new ChannelDescriptor(channel, getNewFileno(), new FileDescriptor()))); | ||||
| 3524 | + openFile.setMainStream(new ChannelStream(new ChannelDescriptor(channel, getNewFileno(), new FileDescriptor()))); | ||||
| 3525 | } catch (InvalidValueException e) { | ||||
| 3526 | throw getRuntime().newErrnoEINVALError(); | ||||
| 3527 | } | ||||
| 3528 | - | ||||
| 3529 | + | ||||
| 3530 | openFile.setMode(openFile.getMainStream().getModes().getOpenFileFlags()); | ||||
| 3531 | - | ||||
| 3532 | + | ||||
| 3533 | registerDescriptor(openFile.getMainStream().getDescriptor()); | ||||
| 3534 | } | ||||
| 3535 | |||||
| 3536 | public RubyIO(Ruby runtime, ShellLauncher.POpenProcess process, ModeFlags modes) { | ||||
| 3537 | super(runtime, runtime.getIO()); | ||||
| 3538 | - | ||||
| 3539 | + | ||||
| 3540 | openFile = new OpenFile(); | ||||
| 3541 | - | ||||
| 3542 | + | ||||
| 3543 | openFile.setMode(modes.getOpenFileFlags() | OpenFile.SYNC); | ||||
| 3544 | openFile.setProcess(process); | ||||
| 3545 | |||||
| 3546 | @@ -204,17 +204,17 @@ | ||||
| 3547 | // Stream-based | ||||
| 3548 | inChannel = Channels.newChannel(process.getInputStream()); | ||||
| 3549 | } | ||||
| 3550 | - | ||||
| 3551 | + | ||||
| 3552 | ChannelDescriptor main = new ChannelDescriptor( | ||||
| 3553 | inChannel, | ||||
| 3554 | getNewFileno(), | ||||
| 3555 | new FileDescriptor()); | ||||
| 3556 | main.setCanBeSeekable(false); | ||||
| 3557 | - | ||||
| 3558 | - openFile.setMainStream(new ChannelStream(getRuntime(), main)); | ||||
| 3559 | + | ||||
| 3560 | + openFile.setMainStream(new ChannelStream(main)); | ||||
| 3561 | registerDescriptor(main); | ||||
| 3562 | } | ||||
| 3563 | - | ||||
| 3564 | + | ||||
| 3565 | if (openFile.isWritable()) { | ||||
| 3566 | Channel outChannel; | ||||
| 3567 | if (process.getOutput() != null) { | ||||
| 3568 | @@ -229,23 +229,23 @@ | ||||
| 3569 | getNewFileno(), | ||||
| 3570 | new FileDescriptor()); | ||||
| 3571 | pipe.setCanBeSeekable(false); | ||||
| 3572 | - | ||||
| 3573 | + | ||||
| 3574 | if (openFile.getMainStream() != null) { | ||||
| 3575 | - openFile.setPipeStream(new ChannelStream(getRuntime(), pipe)); | ||||
| 3576 | + openFile.setPipeStream(new ChannelStream(pipe)); | ||||
| 3577 | } else { | ||||
| 3578 | - openFile.setMainStream(new ChannelStream(getRuntime(), pipe)); | ||||
| 3579 | + openFile.setMainStream(new ChannelStream(pipe)); | ||||
| 3580 | } | ||||
| 3581 | - | ||||
| 3582 | + | ||||
| 3583 | registerDescriptor(pipe); | ||||
| 3584 | } | ||||
| 3585 | } catch (InvalidValueException e) { | ||||
| 3586 | throw getRuntime().newErrnoEINVALError(); | ||||
| 3587 | } | ||||
| 3588 | } | ||||
| 3589 | - | ||||
| 3590 | + | ||||
| 3591 | public RubyIO(Ruby runtime, STDIO stdio) { | ||||
| 3592 | super(runtime, runtime.getIO()); | ||||
| 3593 | - | ||||
| 3594 | + | ||||
| 3595 | openFile = new OpenFile(); | ||||
| 3596 | |||||
| 3597 | try { | ||||
| 3598 | @@ -253,15 +253,13 @@ | ||||
| 3599 | case IN: | ||||
| 3600 | openFile.setMainStream( | ||||
| 3601 | new ChannelStream( | ||||
| 3602 | - runtime, | ||||
| 3603 | // special constructor that accepts stream, not channel | ||||
| 3604 | - new ChannelDescriptor(runtime.getIn(), 0, new ModeFlags(ModeFlags.RDONLY), FileDescriptor.in), | ||||
| 3605 | + new ChannelDescriptor(Channels.newChannel(runtime.getIn()), 0, new ModeFlags(ModeFlags.RDONLY), FileDescriptor.in), | ||||
| 3606 | FileDescriptor.in)); | ||||
| 3607 | break; | ||||
| 3608 | case OUT: | ||||
| 3609 | openFile.setMainStream( | ||||
| 3610 | new ChannelStream( | ||||
| 3611 | - runtime, | ||||
| 3612 | new ChannelDescriptor(Channels.newChannel(runtime.getOut()), 1, new ModeFlags(ModeFlags.WRONLY | ModeFlags.APPEND), FileDescriptor.out), | ||||
| 3613 | FileDescriptor.out)); | ||||
| 3614 | openFile.getMainStream().setSync(true); | ||||
| 3615 | @@ -269,8 +267,7 @@ | ||||
| 3616 | case ERR: | ||||
| 3617 | openFile.setMainStream( | ||||
| 3618 | new ChannelStream( | ||||
| 3619 | - runtime, | ||||
| 3620 | - new ChannelDescriptor(Channels.newChannel(runtime.getErr()), 2, new ModeFlags(ModeFlags.WRONLY | ModeFlags.APPEND), FileDescriptor.err), | ||||
| 3621 | + new ChannelDescriptor(Channels.newChannel(runtime.getErr()), 2, new ModeFlags(ModeFlags.WRONLY | ModeFlags.APPEND), FileDescriptor.err), | ||||
| 3622 | FileDescriptor.err)); | ||||
| 3623 | openFile.getMainStream().setSync(true); | ||||
| 3624 | break; | ||||
| 3625 | @@ -278,25 +275,25 @@ | ||||
| 3626 | } catch (InvalidValueException ex) { | ||||
| 3627 | throw getRuntime().newErrnoEINVALError(); | ||||
| 3628 | } | ||||
| 3629 | - | ||||
| 3630 | + | ||||
| 3631 | openFile.setMode(openFile.getMainStream().getModes().getOpenFileFlags()); | ||||
| 3632 | - | ||||
| 3633 | - registerDescriptor(openFile.getMainStream().getDescriptor()); | ||||
| 3634 | + | ||||
| 3635 | + registerDescriptor(openFile.getMainStream().getDescriptor()); | ||||
| 3636 | } | ||||
| 3637 | - | ||||
| 3638 | + | ||||
| 3639 | public static RubyIO newIO(Ruby runtime, Channel channel) { | ||||
| 3640 | return new RubyIO(runtime, channel); | ||||
| 3641 | } | ||||
| 3642 | - | ||||
| 3643 | + | ||||
| 3644 | public OpenFile getOpenFile() { | ||||
| 3645 | return openFile; | ||||
| 3646 | } | ||||
| 3647 | - | ||||
| 3648 | + | ||||
| 3649 | protected OpenFile getOpenFileChecked() { | ||||
| 3650 | openFile.checkClosed(getRuntime()); | ||||
| 3651 | return openFile; | ||||
| 3652 | } | ||||
| 3653 | - | ||||
| 3654 | + | ||||
| 3655 | private static ObjectAllocator IO_ALLOCATOR = new ObjectAllocator() { | ||||
| 3656 | public IRubyObject allocate(Ruby runtime, RubyClass klass) { | ||||
| 3657 | return new RubyIO(runtime, klass); | ||||
| 3658 | @@ -313,12 +310,12 @@ | ||||
| 3659 | }; | ||||
| 3660 | |||||
| 3661 | ioClass.includeModule(runtime.getEnumerable()); | ||||
| 3662 | - | ||||
| 3663 | + | ||||
| 3664 | // TODO: Implement tty? and isatty. We have no real capability to | ||||
| 3665 | // determine this from java, but if we could set tty status, then | ||||
| 3666 | // we could invoke jruby differently to allow stdin to return true | ||||
| 3667 | // on this. This would allow things like cgi.rb to work properly. | ||||
| 3668 | - | ||||
| 3669 | + | ||||
| 3670 | ioClass.defineAnnotatedMethods(RubyIO.class); | ||||
| 3671 | |||||
| 3672 | // Constants for seek | ||||
| 3673 | @@ -344,7 +341,7 @@ | ||||
| 3674 | return null; | ||||
| 3675 | } | ||||
| 3676 | } | ||||
| 3677 | - | ||||
| 3678 | + | ||||
| 3679 | public Stream getHandler() { | ||||
| 3680 | return getOpenFileChecked().getMainStream(); | ||||
| 3681 | } | ||||
| 3682 | @@ -352,13 +349,13 @@ | ||||







