private static void printErrorPos(ThreadContext context, PrintStream errorStream) { if (context.getFile() != null && context.getFile().length() > 0) { if (context.getFrameName() != null) { errorStream.print(context.getFile() + ":" + context.getLine()); errorStream.print(":in '" + context.getFrameName() + '\''); } else if (context.getLine() != 0) { errorStream.print(context.getFile() + ":" + context.getLine()); } else { errorStream.print(context.getFile()); } } }
public static IRubyObject INTERPRET_METHOD( ThreadContext context, CFG cfg, InterpreterContext interp, String name, RubyModule implClass, boolean isTraceable) { Ruby runtime = interp.getRuntime(); boolean syntheticMethod = name == null || name.equals(""); try { String className = implClass.getName(); if (!syntheticMethod) ThreadContext.pushBacktrace(context, className, name, context.getFile(), context.getLine()); if (isTraceable) methodPreTrace(runtime, context, name, implClass); return interpret(context, cfg, interp); } finally { if (isTraceable) { try { methodPostTrace(runtime, context, name, implClass); } finally { if (!syntheticMethod) ThreadContext.popBacktrace(context); } } else { if (!syntheticMethod) ThreadContext.popBacktrace(context); } } }
@Override public IRubyObject interpret( Ruby runtime, ThreadContext context, IRubyObject self, Block aBlock) { Block block = SharedScopeBlock.newInterpretedSharedScopeClosure( context, this, context.getCurrentScope(), self); try { while (true) { try { String savedFile = context.getFile(); int savedLine = context.getLine(); IRubyObject recv = null; try { recv = iterNode.interpret(runtime, context, self, aBlock); } finally { context.setFileAndLine(savedFile, savedLine); } return callAdapter.call(context, self, recv, block); } catch (JumpException.RetryJump rj) { // do nothing, allow loop to retry } } } catch (JumpException.BreakJump bj) { return (IRubyObject) bj.getValue(); } }
@JRubyMethod(name = "initialize", frame = true, visibility = Visibility.PRIVATE) public IRubyObject initialize(ThreadContext context, Block procBlock) { if (!procBlock.isGiven()) { throw getRuntime().newArgumentError("tried to create Proc object without a block"); } if (isLambda() && procBlock == null) { // TODO: warn "tried to create Proc object without a block" } block = procBlock.cloneBlock(); if (isThread()) { // modify the block with a new backref/lastline-grabbing scope StaticScope oldScope = block.getBody().getStaticScope(); StaticScope newScope = new BlockStaticScope(oldScope.getEnclosingScope(), oldScope.getVariables()); newScope.setBackrefLastlineScope(true); newScope.setPreviousCRefScope(oldScope.getPreviousCRefScope()); newScope.setModule(oldScope.getModule()); block.getBody().setStaticScope(newScope); } block.type = type; block.setProcObject(this); file = context.getFile(); line = context.getLine(); return this; }
@JRubyMethod(rest = true, visibility = PRIVATE) public IRubyObject initialize(ThreadContext context, IRubyObject[] args, Block block) { Ruby runtime = getRuntime(); if (!block.isGiven()) throw runtime.newThreadError("must be called with a block"); try { RubyRunnable runnable = new RubyRunnable(this, args, context.getFrames(0), block); if (RubyInstanceConfig.POOLING_ENABLED) { FutureThread futureThread = new FutureThread(this, runnable); threadImpl = futureThread; addToCorrectThreadGroup(context); threadImpl.start(); // JRUBY-2380, associate future early so it shows up in Thread.list right away, in case it // doesn't run immediately runtime.getThreadService().associateThread(futureThread.getFuture(), this); } else { Thread thread = new Thread(runnable); thread.setDaemon(true); thread.setName( "Ruby" + thread.getName() + ": " + context.getFile() + ":" + (context.getLine() + 1)); threadImpl = new NativeThread(this, thread); addToCorrectThreadGroup(context); // JRUBY-2380, associate thread early so it shows up in Thread.list right away, in case it // doesn't run immediately runtime.getThreadService().associateThread(thread, this); threadImpl.start(); } // We yield here to hopefully permit the target thread to schedule // MRI immediately schedules it, so this is close but not exact Thread.yield(); return this; } catch (OutOfMemoryError oome) { if (oome.getMessage().equals("unable to create new native thread")) { throw runtime.newThreadError(oome.getMessage()); } throw oome; } catch (SecurityException ex) { throw runtime.newThreadError(ex.getMessage()); } }
private IRubyObject startWith(ThreadedRunnable runnable) throws RaiseException, OutOfMemoryError { Ruby runtime = getRuntime(); ThreadContext context = runtime.getCurrentContext(); try { if (RubyInstanceConfig.POOLING_ENABLED) { FutureThread futureThread = new FutureThread(this, runnable); threadImpl = futureThread; addToCorrectThreadGroup(context); threadImpl.start(); // JRUBY-2380, associate future early so it shows up in Thread.list right away, in case it // doesn't run immediately runtime.getThreadService().associateThread(futureThread.getFuture(), this); } else { Thread thread = new Thread(runnable); thread.setDaemon(true); thread.setName( "Ruby" + thread.getName() + ": " + context.getFile() + ":" + (context.getLine() + 1)); threadImpl = new NativeThread(this, thread); addToCorrectThreadGroup(context); // JRUBY-2380, associate thread early so it shows up in Thread.list right away, in case it // doesn't run immediately runtime.getThreadService().associateThread(thread, this); threadImpl.start(); } // We yield here to hopefully permit the target thread to schedule // MRI immediately schedules it, so this is close but not exact Thread.yield(); return this; } catch (OutOfMemoryError oome) { if (oome.getMessage().equals("unable to create new native thread")) { throw runtime.newThreadError(oome.getMessage()); } throw oome; } catch (SecurityException ex) { throw runtime.newThreadError(ex.getMessage()); } }
public static IRubyObject[] setupArgs( Ruby runtime, ThreadContext context, Node node, IRubyObject self, Block aBlock) { if (node == null) return IRubyObject.NULL_ARRAY; if (node instanceof ArrayNode) { ArrayNode argsArrayNode = (ArrayNode) node; String savedFile = context.getFile(); int savedLine = context.getLine(); int size = argsArrayNode.size(); IRubyObject[] argsArray = new IRubyObject[size]; for (int i = 0; i < size; i++) { argsArray[i] = argsArrayNode.get(i).interpret(runtime, context, self, aBlock); } context.setFileAndLine(savedFile, savedLine); return argsArray; } return ArgsUtil.convertToJavaArray(node.interpret(runtime, context, self, aBlock)); }
protected static String printBacktraceMRI(RubyException exception) { Ruby runtime = exception.getRuntime(); ThreadContext context = runtime.getCurrentContext(); IRubyObject backtrace = exception.callMethod(context, "backtrace"); ByteArrayOutputStream baos = new ByteArrayOutputStream(); PrintStream errorStream = new PrintStream(baos); boolean printedPosition = false; if (backtrace.isNil() || !(backtrace instanceof RubyArray)) { if (context.getFile() != null && context.getFile().length() > 0) { errorStream.print(context.getFile() + ":" + context.getLine()); printedPosition = true; } else { errorStream.print(context.getLine()); printedPosition = true; } } else if (((RubyArray) backtrace).getLength() == 0) { printErrorPos(context, errorStream); } else { IRubyObject mesg = ((RubyArray) backtrace).first(); if (mesg.isNil()) { printErrorPos(context, errorStream); } else { errorStream.print(mesg); printedPosition = true; } } RubyClass type = exception.getMetaClass(); String info = exception.toString(); if (printedPosition) errorStream.print(": "); if (type == runtime.getRuntimeError() && (info == null || info.length() == 0)) { errorStream.print(": unhandled exception\n"); } else { String path = type.getName(); if (info.length() == 0) { errorStream.print(path + '\n'); } else { if (path.startsWith("#")) { path = null; } String tail = null; if (info.indexOf("\n") != -1) { tail = info.substring(info.indexOf("\n") + 1); info = info.substring(0, info.indexOf("\n")); } errorStream.print(info); if (path != null) { errorStream.print(" (" + path + ")\n"); } if (tail != null) { errorStream.print(tail + '\n'); } } } exception.printBacktrace(errorStream); return new String(baos.toByteArray()); }
public static void callTraceFunction(Ruby runtime, ThreadContext context, RubyEvent event) { String name = context.getFrameName(); RubyModule type = context.getFrameKlazz(); runtime.callEventHooks(context, event, context.getFile(), context.getLine(), name, type); }