private IRubyObject handleReturnJump( ThreadContext context, JumpException.ReturnJump rj, int jumpTarget) { int target = rj.getTarget(); Ruby runtime = context.getRuntime(); // lambda always just returns the value if (target == jumpTarget && isLambda()) { return (IRubyObject) rj.getValue(); } // returns can't propagate out of threads if (isThread()) { throw runtime.newThreadError("return can't jump across threads"); } // If the block-receiving method is not still active and the original // enclosing frame is no longer on the stack, it's a bad return. // FIXME: this is not very efficient for cases where it won't error if (target == jumpTarget && !context.isJumpTargetAlive(target, 1)) { throw runtime.newLocalJumpError( RubyLocalJumpError.Reason.RETURN, (IRubyObject) rj.getValue(), "unexpected return"); } // otherwise, let it propagate throw rj; }
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); } } }
@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( name = {"call", "[]", "yield"}, rest = true, frame = true, compat = CompatVersion.RUBY1_9) public IRubyObject call19(ThreadContext context, IRubyObject[] args, Block block) { if (isLambda()) { this.block.arity().checkArity(context.getRuntime(), args.length); } if (isProc()) { List<IRubyObject> list = new ArrayList<IRubyObject>(Arrays.asList(args)); int required = this.block.arity().required(); if (this.block.arity().isFixed()) { if (required > args.length) { for (int i = args.length; i < required; i++) { list.add(context.getRuntime().getNil()); } args = list.toArray(args); } else if (required < args.length) { args = list.subList(0, required).toArray(args); } } } return call(context, args, null, block); }
public static IRubyObject INTERPRET_METHOD( ThreadContext context, InterpretedIRMethod irMethod, IRubyObject self, String name, IRubyObject[] args, Block block, Block.Type blockType, boolean isTraceable) { Ruby runtime = context.runtime; IRScope scope = irMethod.getIRMethod(); RubyModule implClass = irMethod.getImplementationClass(); Visibility viz = irMethod.getVisibility(); boolean syntheticMethod = name == null || name.equals(""); try { if (!syntheticMethod) ThreadContext.pushBacktrace(context, name, scope.getFileName(), context.getLine()); if (isTraceable) methodPreTrace(runtime, context, name, implClass); return interpret(context, self, scope, viz, implClass, args, block, blockType); } finally { if (isTraceable) { try { methodPostTrace(runtime, context, name, implClass); } finally { if (!syntheticMethod) ThreadContext.popBacktrace(context); } } else { if (!syntheticMethod) ThreadContext.popBacktrace(context); } } }
@Override public Object interpret( ThreadContext context, DynamicScope currDynScope, IRubyObject self, Object[] temp, Block aBlock) { // FIXME: Receiver is not being used...should we be retrieving it? IRubyObject receiver = (IRubyObject) getReceiver().retrieve(context, self, currDynScope, temp); IRubyObject[] args = prepareArguments(context, self, getCallArgs(), currDynScope, temp); Block block = prepareBlock(context, self, currDynScope, temp); RubyModule klazz = context.getFrameKlazz(); // SSS FIXME: Even though we may know the method name in some instances, // we are not making use of it here. It is cleaner in the sense of not // relying on implicit information whose data flow doesn't show up in the IR. String methodName = context.getCurrentFrame().getName(); // methAddr.getName(); checkSuperDisabledOrOutOfMethod(context, klazz, methodName); RubyClass superClass = RuntimeHelpers.findImplementerIfNecessary(self.getMetaClass(), klazz).getSuperClass(); DynamicMethod method = superClass != null ? superClass.searchMethod(methodName) : UndefinedMethod.INSTANCE; Object rVal = method.isUndefined() ? RuntimeHelpers.callMethodMissing( context, self, method.getVisibility(), methodName, CallType.SUPER, args, block) : method.call(context, self, superClass, methodName, args, block); return hasUnusedResult() ? null : rVal; }
@JRubyMethod( name = {"create_invoker", "createInvoker"}, required = 5) public IRubyObject createInvoker(ThreadContext context, IRubyObject[] args) { RubyArray paramTypes = (RubyArray) args[3]; NativeParam[] nativeParamTypes = new NativeParam[paramTypes.size()]; for (int i = 0; i < paramTypes.size(); ++i) { IRubyObject obj = (IRubyObject) paramTypes.entry(i); if (obj instanceof NativeParam) { nativeParamTypes[i] = (NativeParam) obj; } else if (obj instanceof RubyInteger) { nativeParamTypes[i] = NativeType.valueOf(Util.int32Value(obj)); } else { context.getRuntime().newArgumentError("Invalid parameter type"); } } try { return createInvoker( context.getRuntime(), args[0].isNil() ? null : args[0].toString(), args[1].toString(), NativeType.valueOf(Util.int32Value(args[2])), nativeParamTypes, args[4].toString()); } catch (UnsatisfiedLinkError ex) { return context.getRuntime().getNil(); } }
@Override public IRubyObject interpret( Ruby runtime, ThreadContext context, IRubyObject self, Block aBlock) { // Serialization killed our dynamic scope. We can just create an empty one // since serialization cannot serialize an eval (which is the only thing // which is capable of having a non-empty dynamic scope). if (scope == null) { scope = DynamicScope.newDynamicScope(staticScope); } StaticScope theStaticScope = scope.getStaticScope(); // Each root node has a top-level scope that we need to push context.preScopedBody(scope); if (theStaticScope.getModule() == null) { theStaticScope.setModule(runtime.getObject()); } try { return bodyNode.interpret(runtime, context, self, aBlock); } finally { context.postScopedBody(); } }
/** do_coerce */ protected final RubyArray doCoerce(ThreadContext context, IRubyObject other, boolean err) { if (!other.respondsTo("coerce")) { if (err) { coerceRescue(context, other); } return null; } final Ruby runtime = context.runtime; final IRubyObject $ex = context.getErrorInfo(); final IRubyObject result; try { result = coerceBody(context, other); } catch (RaiseException e) { // e.g. NoMethodError: undefined method `coerce' if (e.getException().kind_of_p(context, runtime.getStandardError()).isTrue()) { context.setErrorInfo($ex); // restore $! RubyWarnings warnings = context.runtime.getWarnings(); warnings.warn("Numerical comparison operators will no more rescue exceptions of #coerce"); warnings.warn("in the next release. Return nil in #coerce if the coercion is impossible."); if (err) { coerceFailed(context, other); } return null; } else { throw e; } } return coerceResult(runtime, result, err); }
public static IRubyObject INTERPRET_METHOD( Ruby runtime, ThreadContext context, String file, int line, RubyModule implClass, Node node, String name, IRubyObject self, Block block, boolean isTraceable) { try { ThreadContext.pushBacktrace(context, name, file, line); if (isTraceable) methodPreTrace(runtime, context, name, implClass); return node.interpret(runtime, context, self, block); } finally { if (isTraceable) { try { methodPostTrace(runtime, context, name, implClass); } finally { ThreadContext.popBacktrace(context); } } else { ThreadContext.popBacktrace(context); } } }
@JRubyMethod(name = "root=") public IRubyObject root_set(ThreadContext context, IRubyObject newRoot_) { // in case of document fragment, temporary root node should be deleted. // Java can't have a root whose value is null. Instead of setting null, // the method sets user data so that other methods are able to know the root // should be nil. if (newRoot_ instanceof RubyNil) { getDocument().getDocumentElement().setUserData(NokogiriHelpers.VALID_ROOT_NODE, false, null); return newRoot_; } XmlNode newRoot = asXmlNode(context, newRoot_); IRubyObject root = root(context); if (root.isNil()) { Node newRootNode; if (getDocument() == newRoot.getOwnerDocument()) { newRootNode = newRoot.node; } else { // must copy otherwise newRoot may exist in two places // with different owner document. newRootNode = getDocument().importNode(newRoot.node, true); } add_child_node(context, getCachedNodeOrCreate(context.getRuntime(), newRootNode)); } else { Node rootNode = asXmlNode(context, root).node; ((XmlNode) getCachedNodeOrCreate(context.getRuntime(), rootNode)) .replace_node(context, newRoot); } return newRoot; }
public static void main(String[] args) { // Ensure we're not running on GCJ, since it's not supported and leads to weird errors if (Platform.IS_GCJ) { System.err.println("Fatal: GCJ (GNU Compiler for Java) is not supported by JRuby."); System.exit(1); } Main main = new Main(); try { int status = main.run(args); if (status != 0) { System.exit(status); } } catch (RaiseException re) { throw re; } catch (Throwable t) { // print out as a nice Ruby backtrace System.err.println(ThreadContext.createRawBacktraceStringFromThrowable(t)); while ((t = t.getCause()) != null) { System.err.println("Caused by:"); System.err.println(ThreadContext.createRawBacktraceStringFromThrowable(t)); } System.exit(1); } }
@Override public Object interpret( ThreadContext context, DynamicScope currDynScope, IRubyObject self, Object[] temp, Block block) { // SSS FIXME: This is ugly and needs fixing. Is there another way of capturing this info? RubyModule containerModule = (candidateScope == null) ? null : candidateScope.getStaticScope().getModule(); if (containerModule == null) containerModule = ASTInterpreter.getClassVariableBase(context, context.getRuntime()); if (containerModule == null && object != null) { IRubyObject arg = (IRubyObject) object.retrieve(context, self, currDynScope, temp); // SSS: What is the right thing to do here? containerModule = arg .getMetaClass(); // (arg instanceof RubyClass) ? ((RubyClass)arg).getRealClass() : // arg.getType(); } if (containerModule == null) throw context.getRuntime().newTypeError("no class/module to define class variable"); return containerModule; }
/** * This is the command-line entry point for JRuby, and should ONLY be used by Java when starting * up JRuby from a command-line. Use other mechanisms when embedding JRuby into another * application. * * @param args command-line args, provided by the JVM. */ public static void main(String[] args) { doGCJCheck(); Main main; if (DripMain.DRIP_RUNTIME != null) { main = new Main(DripMain.DRIP_CONFIG, true); } else { main = new Main(true); } try { Status status = main.run(args); if (status.isExit()) { System.exit(status.getStatus()); } } catch (RaiseException rj) { System.exit(handleRaiseException(rj)); } catch (Throwable t) { // print out as a nice Ruby backtrace System.err.println(ThreadContext.createRawBacktraceStringFromThrowable(t)); while ((t = t.getCause()) != null) { System.err.println("Caused by:"); System.err.println(ThreadContext.createRawBacktraceStringFromThrowable(t)); } System.exit(1); } }
@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(); } }
private ByteList doReceive(ThreadContext context, int length) { Ruby runtime = context.runtime; ByteBuffer buf = ByteBuffer.allocate(length); try { context.getThread().beforeBlockingCall(); int read = openFile.getMainStreamSafe().getDescriptor().read(buf); if (read == 0) return null; return new ByteList(buf.array(), 0, buf.position()); } catch (BadDescriptorException e) { throw runtime.newIOError("bad descriptor"); } catch (IOException e) { // All errors to sysread should be SystemCallErrors, but on a closed stream // Ruby returns an IOError. Java throws same exception for all errors so // we resort to this hack... if ("Socket not open".equals(e.getMessage())) { throw runtime.newIOError(e.getMessage()); } throw runtime.newSystemCallError(e.getMessage()); } finally { context.getThread().afterBlockingCall(); } }
@JRubyMethod( name = { "basic_quote_characters", "basic_quote_characters=", "completer_quote_characters", "completer_quote_characters=", "completer_word_break_characters", "completer_word_break_characters=", "completion_append_character", "completion_proc", "emacs_editing_mode", "emacs_editing_mode?", "filename_quote_characters", "filename_quote_characters=", "vi_editing_mode", "vi_editing_mode?", "set_screen_size" }, frame = true, module = true, visibility = Visibility.PRIVATE, compat = CompatVersion.RUBY1_9) public static IRubyObject unimplemented19(ThreadContext context, IRubyObject recv) throws Exception { Ruby runtime = context.getRuntime(); runtime.secure(4); String err = context.getFrameName() + "() function is unimplemented on this machine"; throw runtime.newNotImplementedError(err); }
@Override public Label interpret(InterpreterContext interp) { RubyModule clazz = (RubyModule) getArg().retrieve(interp); String name = method.getName(); ThreadContext context = interp.getContext(); Visibility visibility = context.getCurrentVisibility(); if (name == "initialize" || name == "initialize_copy" || visibility == Visibility.MODULE_FUNCTION) { visibility = Visibility.PRIVATE; } DynamicMethod newMethod = new InterpretedIRMethod(method, visibility, clazz); clazz.addMethod(name, newMethod); if (visibility == Visibility.MODULE_FUNCTION) { clazz .getSingletonClass() .addMethod( name, new WrapperMethod(clazz.getSingletonClass(), newMethod, Visibility.PUBLIC)); clazz.callMethod(context, "singleton_method_added", interp.getRuntime().fastNewSymbol(name)); } // 'class << state.self' and 'class << obj' uses defn as opposed to defs if (clazz.isSingleton()) { ((MetaClass) clazz) .getAttached() .callMethod(context, "singleton_method_added", interp.getRuntime().fastNewSymbol(name)); } else { clazz.callMethod(context, "method_added", interp.getRuntime().fastNewSymbol(name)); } return null; }
/** match_post_match */ @JRubyMethod(name = "post_match") public IRubyObject post_match(ThreadContext context) { check(); if (begin == -1) return context.getRuntime().getNil(); return makeShared(context.getRuntime(), str, end, str.getByteList().length() - end) .infectBy(this); }
public void put( ThreadContext context, StructLayout.Storage cache, Member m, IRubyObject ptr, IRubyObject value) { if (value instanceof Pointer) { m.getMemoryIO(ptr).putMemoryIO(m.offset, ((Pointer) value).getMemoryIO()); } else if (value instanceof Struct) { MemoryIO mem = ((Struct) value).getMemoryIO(); if (!(mem instanceof DirectMemoryIO)) { throw context .getRuntime() .newArgumentError("Struct memory not backed by a native pointer"); } m.getMemoryIO(ptr).putMemoryIO(m.offset, mem); } else if (value instanceof RubyInteger) { m.getMemoryIO(ptr).putAddress(m.offset, Util.int64Value(ptr)); } else if (value.respondsTo("to_ptr")) { IRubyObject addr = value.callMethod(context, "to_ptr"); if (addr instanceof Pointer) { m.getMemoryIO(ptr).putMemoryIO(m.offset, ((Pointer) addr).getMemoryIO()); } else { throw context.getRuntime().newArgumentError("Invalid pointer value"); } } else if (value.isNil()) { m.getMemoryIO(ptr).putAddress(m.offset, 0L); } else { throw context.getRuntime().newArgumentError("Invalid pointer value"); } cache.putReference(m, value); }
@JRubyMethod(required = 4) public IRubyObject initialize(ThreadContext context, IRubyObject[] args) { if (!(args[2] instanceof MappedType)) { throw context .getRuntime() .newTypeError( args[2], context .getRuntime() .fastGetModule("FFI") .fastGetClass("Type") .fastGetClass("Mapped")); } if (!(args[3] instanceof Field)) { throw context .getRuntime() .newTypeError( args[3], context .getRuntime() .fastGetModule("FFI") .fastGetClass("StructLayout") .fastGetClass("Field")); } init( args[0], args[2], args[1], new MappedFieldIO((MappedType) args[2], ((Field) args[3]).getFieldIO())); return this; }
protected void post(InterpreterContext ic, ThreadContext context) { // update call stacks (pop: ..) context.popFrame(); if (ic.popDynScope()) { context.popScope(); } }
protected Object interpretSuper( ThreadContext context, IRubyObject self, IRubyObject[] args, Block block) { // SSS FIXME: We should check in the current module (for instance methods) or the current // module's meta class (for class methods) // // RubyModule currM = context.getCurrentScope().getStaticScope().getModule(); // RubyModule klazz = (isInstanceMethodSuper) ? currM : currM.getMetaClass(); // // The question is how do we know what this 'super' ought to do? // For 'super' that occurs in a method scope, this is easy to figure out. // But, what about 'super' that occurs in block scope? How do we figure that out? RubyModule klazz = context.getFrameKlazz(); // SSS FIXME: Even though we may know the method name in some instances, // we are not making use of it here. String methodName = context.getCurrentFrame().getName(); // methAddr.getName(); checkSuperDisabledOrOutOfMethod(context, klazz, methodName); RubyClass superClass = RuntimeHelpers.findImplementerIfNecessary(self.getMetaClass(), klazz).getSuperClass(); DynamicMethod method = superClass != null ? superClass.searchMethod(methodName) : UndefinedMethod.INSTANCE; Object rVal = method.isUndefined() ? RuntimeHelpers.callMethodMissing( context, self, method.getVisibility(), methodName, CallType.SUPER, args, block) : method.call(context, self, superClass, methodName, args, block); return hasUnusedResult() ? null : rVal; }
private IRubyObject INTERPRET_METHOD( ThreadContext context, InterpreterContext ic, RubyModule implClass, IRubyObject self, String name, IRubyObject arg1, IRubyObject arg2, IRubyObject arg3, Block block) { try { ThreadContext.pushBacktrace(context, name, ic.getFileName(), context.getLine()); if (ic.hasExplicitCallProtocol()) { return ic.engine.interpret( context, self, ic, implClass, name, arg1, arg2, arg3, block, null); } else { try { this.pre(ic, context, self, name, block, implClass); return ic.engine.interpret( context, self, ic, implClass, name, arg1, arg2, arg3, block, null); } finally { this.post(ic, context); } } } finally { ThreadContext.popBacktrace(context); } }
public final void marshal( ThreadContext context, InvocationBuffer buffer, IRubyObject parameter) { if (!(parameter instanceof Struct)) { throw context .getRuntime() .newTypeError( "wrong argument type " + parameter.getMetaClass().getName() + " (expected instance of FFI::Struct)"); } IRubyObject memory = ((Struct) parameter).getMemory(); if (!(memory instanceof AbstractMemory)) { throw context .getRuntime() .newTypeError("wrong struct memory type " + memory.getMetaClass().getName()); } MemoryIO io = ((AbstractMemory) memory).getMemoryIO(); if (io instanceof DirectMemoryIO) { if (io.isNull()) { throw context .getRuntime() .newRuntimeError("Cannot use a NULL pointer as a struct by value argument"); } buffer.putStruct(((DirectMemoryIO) io).getAddress()); } else if (io instanceof ArrayMemoryIO) { ArrayMemoryIO aio = (ArrayMemoryIO) io; buffer.putStruct(aio.array(), aio.arrayOffset()); } else { throw context.getRuntime().newRuntimeError("Invalid struct memory"); } }
@Override public Object retrieve(ThreadContext context, IRubyObject self, Object[] temp) { BlockBody body = closure.getBlockBody(); closure.getStaticScope().determineModule(); Binding binding = context.currentBinding(self, context.getCurrentScope()); return new Block(body, binding); }
/** int_succ */ @JRubyMethod(name = {"succ", "next"}) public IRubyObject succ(ThreadContext context) { if (this instanceof RubyFixnum) { return RubyFixnum.newFixnum(context.getRuntime(), getLongValue() + 1L); } else { return callMethod(context, "+", RubyFixnum.one(context.getRuntime())); } }
protected void pre( ThreadContext context, String name, IRubyObject self, Block block, Ruby runtime) { if (needsScope) { context.preMethodFrameAndScope(getImplementationClass(), name, self, block, staticScope); } else { context.preMethodFrameAndDummyScope(getImplementationClass(), name, self, block, staticScope); } }
protected static RubyStackTraceElement[] getBacktrace( ThreadContext context, boolean nativeException, boolean full) { return ThreadContext.gatherHybridBacktrace( context.getRuntime(), context.createBacktrace2(0, nativeException), Thread.currentThread().getStackTrace(), full); }
@JRubyMethod(name = "<=>", required = 1) public IRubyObject op_cmp(ThreadContext context, IRubyObject other) { if (other instanceof RubyTime) { return context.getRuntime().newFixnum(cmp((RubyTime) other)); } return context.getRuntime().getNil(); }