# HG changeset patch # User Chris Seaton # Date 1393895326 0 # Node ID d2c84a0bf37a5f340b69b81a97ec3f20acff5b5f # Parent fde464340755d4db5907b086612366f6acc9b1bf Remove Ruby implementation. diff -r fde464340755 -r d2c84a0bf37a .hgignore --- a/.hgignore Fri Feb 28 16:35:52 2014 -0800 +++ b/.hgignore Tue Mar 04 01:08:46 2014 +0000 @@ -85,5 +85,3 @@ agent/build/* agent/make/filelist agent/make/sa17.tar.gz -graal/com.oracle.truffle.ruby.test/specs/mspec -graal/com.oracle.truffle.ruby.test/specs/rubyspec diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/CoreSource.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/CoreSource.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes; - -import java.io.*; - -import com.oracle.truffle.api.*; - -/** - * Singleton source used for core method nodes. - */ -public final class CoreSource implements Source { - - private final String name; - - public CoreSource(String name) { - this.name = name; - } - - public String getName() { - return name; - } - - public String getCode() { - return name; - } - - @Override - public String toString() { - return name; - } - - public String getPath() { - return null; - } - - public Reader getReader() { - return null; - } - - public InputStream getInputStream() { - return null; - } - - public String getCode(int lineNumber) { - return null; - } - - public int getLineCount() { - return 0; - } - - public int getLineNumber(int offset) { - return 0; - } - - public int getLineStartOffset(int lineNumber) { - return 0; - } - - public int getLineLength(int lineNumber) { - return 0; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/CoreSourceSection.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/CoreSourceSection.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes; - -import com.oracle.truffle.api.*; - -/** - * Source sections used for core method nodes. - */ -public final class CoreSourceSection implements NullSourceSection { - - private final String name; - - public CoreSourceSection(String name) { - this.name = name; - } - - public Source getSource() { - return new CoreSource(name); - } - - public int getStartLine() { - return 0; - } - - public int getStartColumn() { - return 0; - } - - public int getCharIndex() { - return 0; - } - - @Override - public int getCharLength() { - return 0; - } - - public int getCharEndIndex() { - return 0; - } - - public String getIdentifier() { - return null; - } - - public String getCode() { - return name; - } - - @Override - public String toString() { - return name; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/DefinedNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/DefinedNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.runtime.*; - -/** - * Switches execution to the parallel {@link RubyNode#isDefined} semantic path. Represents the - * {@code defined?} keyword in Ruby. - */ -@NodeInfo(shortName = "defined") -public class DefinedNode extends RubyNode { - - @Child protected RubyNode child; - - public DefinedNode(RubyContext context, SourceSection sourceSection, RubyNode child) { - super(context, sourceSection); - this.child = adoptChild(child); - } - - @Override - public Object execute(VirtualFrame frame) { - return child.isDefined(frame); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/InlinableMethodImplementation.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/InlinableMethodImplementation.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.call.*; -import com.oracle.truffle.ruby.runtime.methods.*; - -/** - * A method implementation that also carries the pristine root node and frame descriptor, from which - * we can inline. - * - * @see InlinedUnboxedDispatchNode - * @see InlinedBoxedDispatchNode - * @see InlineHeuristic - */ -public class InlinableMethodImplementation extends CallTargetMethodImplementation { - - private final FrameDescriptor frameDescriptor; - private final RubyRootNode pristineRootNode; - - public final boolean alwaysInline; - public final boolean shouldAppendCallNode; - - public InlinableMethodImplementation(CallTarget callTarget, MaterializedFrame declarationFrame, FrameDescriptor frameDescriptor, RubyRootNode pristineRootNode, boolean alwaysInline, - boolean shouldAppendCallNode) { - super(callTarget, declarationFrame); - - assert frameDescriptor != null; - assert pristineRootNode != null; - - this.frameDescriptor = frameDescriptor; - this.pristineRootNode = pristineRootNode; - this.alwaysInline = alwaysInline; - this.shouldAppendCallNode = shouldAppendCallNode; - } - - public FrameDescriptor getFrameDescriptor() { - return frameDescriptor; - } - - public RubyRootNode getPristineRootNode() { - return pristineRootNode; - } - - public RubyRootNode getCloneOfPristineRootNode() { - return NodeUtil.cloneNode(pristineRootNode); - } - - public boolean alwaysInline() { - return alwaysInline; - } - - public boolean getShouldAppendCallNode() { - return shouldAppendCallNode; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/ReadNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/ReadNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes; - -/** - * Interface for all nodes which read something, providing a method to transform them to write the - * same thing. - */ -public interface ReadNode { - - /** - * Return a new node that performs the equivalent write operation to this node's read, using the - * supplied node for the right-hand-side. - */ - RubyNode makeWriteNode(RubyNode rhs); - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/RubyNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/RubyNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,216 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes; - -import java.math.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.call.*; -import com.oracle.truffle.ruby.nodes.debug.*; -import com.oracle.truffle.ruby.nodes.yield.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.core.array.*; -import com.oracle.truffle.ruby.runtime.core.range.*; -import com.oracle.truffle.ruby.runtime.methods.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -/** - * Base class for most nodes in Ruby. - * - * @see DispatchNode - * @see YieldDispatchNode - */ -@TypeSystemReference(RubyTypes.class) -public abstract class RubyNode extends Node { - - private final RubyContext context; - - public RubyNode(RubyContext context, SourceSection sourceSection) { - super(sourceSection); - - assert context != null; - assert sourceSection != null; - - this.context = context; - } - - public RubyNode(RubyNode prev) { - this(prev.context, prev.getSourceSection()); - } - - public abstract Object execute(VirtualFrame frame); - - /** - * Ruby's parallel semantic path. - * - * @see DefinedNode - */ - public Object isDefined(@SuppressWarnings("unused") VirtualFrame frame) { - throw new UnsupportedOperationException("no definition for " + getClass().getName()); - } - - public RubyArray executeArray(VirtualFrame frame) throws UnexpectedResultException { - return RubyTypesGen.RUBYTYPES.expectRubyArray(execute(frame)); - } - - public BigInteger executeBignum(VirtualFrame frame) throws UnexpectedResultException { - return RubyTypesGen.RUBYTYPES.expectBigInteger(execute(frame)); - } - - public boolean executeBoolean(VirtualFrame frame) throws UnexpectedResultException { - return RubyTypesGen.RUBYTYPES.expectBoolean(execute(frame)); - } - - public RubyBignum executeBoxedBignum(VirtualFrame frame) throws UnexpectedResultException { - return RubyTypesGen.RUBYTYPES.expectRubyBignum(execute(frame)); - } - - public RubyFixnum executeBoxedFixnum(VirtualFrame frame) throws UnexpectedResultException { - return RubyTypesGen.RUBYTYPES.expectRubyFixnum(execute(frame)); - } - - public RubyFloat executeBoxedFloat(VirtualFrame frame) throws UnexpectedResultException { - return RubyTypesGen.RUBYTYPES.expectRubyFloat(execute(frame)); - } - - public int executeFixnum(VirtualFrame frame) throws UnexpectedResultException { - return RubyTypesGen.RUBYTYPES.expectInteger(execute(frame)); - } - - public FixnumRange executeFixnumRange(VirtualFrame frame) throws UnexpectedResultException { - return RubyTypesGen.RUBYTYPES.expectFixnumRange(execute(frame)); - } - - public double executeFloat(VirtualFrame frame) throws UnexpectedResultException { - return RubyTypesGen.RUBYTYPES.expectDouble(execute(frame)); - } - - public NilPlaceholder executeNilPlaceholder(VirtualFrame frame) throws UnexpectedResultException { - return RubyTypesGen.RUBYTYPES.expectNilPlaceholder(execute(frame)); - } - - public Node executeNode(VirtualFrame frame) throws UnexpectedResultException { - return RubyTypesGen.RUBYTYPES.expectNode(execute(frame)); - } - - public Object[] executeObjectArray(VirtualFrame frame) throws UnexpectedResultException { - return RubyTypesGen.RUBYTYPES.expectObjectArray(execute(frame)); - } - - public ObjectRange executeObjectRange(VirtualFrame frame) throws UnexpectedResultException { - return RubyTypesGen.RUBYTYPES.expectObjectRange(execute(frame)); - } - - public RubyBasicObject executeRubyBasicObject(VirtualFrame frame) throws UnexpectedResultException { - return RubyTypesGen.RUBYTYPES.expectRubyBasicObject(execute(frame)); - } - - public RubyBinding executeRubyBinding(VirtualFrame frame) throws UnexpectedResultException { - return RubyTypesGen.RUBYTYPES.expectRubyBinding(execute(frame)); - } - - public RubyClass executeRubyClass(VirtualFrame frame) throws UnexpectedResultException { - return RubyTypesGen.RUBYTYPES.expectRubyClass(execute(frame)); - } - - public RubyContinuation executeRubyContinuation(VirtualFrame frame) throws UnexpectedResultException { - return RubyTypesGen.RUBYTYPES.expectRubyContinuation(execute(frame)); - } - - public RubyException executeRubyException(VirtualFrame frame) throws UnexpectedResultException { - return RubyTypesGen.RUBYTYPES.expectRubyException(execute(frame)); - } - - public RubyFiber executeRubyFiber(VirtualFrame frame) throws UnexpectedResultException { - return RubyTypesGen.RUBYTYPES.expectRubyFiber(execute(frame)); - } - - public RubyFile executeRubyFile(VirtualFrame frame) throws UnexpectedResultException { - return RubyTypesGen.RUBYTYPES.expectRubyFile(execute(frame)); - } - - public RubyHash executeRubyHash(VirtualFrame frame) throws UnexpectedResultException { - return RubyTypesGen.RUBYTYPES.expectRubyHash(execute(frame)); - } - - public RubyMatchData executeRubyMatchData(VirtualFrame frame) throws UnexpectedResultException { - return RubyTypesGen.RUBYTYPES.expectRubyMatchData(execute(frame)); - } - - public RubyMethod executeRubyMethod(VirtualFrame frame) throws UnexpectedResultException { - return RubyTypesGen.RUBYTYPES.expectRubyMethod(execute(frame)); - } - - public RubyModule executeRubyModule(VirtualFrame frame) throws UnexpectedResultException { - return RubyTypesGen.RUBYTYPES.expectRubyModule(execute(frame)); - } - - public RubyNilClass executeRubyNilClass(VirtualFrame frame) throws UnexpectedResultException { - return RubyTypesGen.RUBYTYPES.expectRubyNilClass(execute(frame)); - } - - public RubyObject executeRubyObject(VirtualFrame frame) throws UnexpectedResultException { - return RubyTypesGen.RUBYTYPES.expectRubyObject(execute(frame)); - } - - public RubyProc executeRubyProc(VirtualFrame frame) throws UnexpectedResultException { - return RubyTypesGen.RUBYTYPES.expectRubyProc(execute(frame)); - } - - public RubyRange executeRubyRange(VirtualFrame frame) throws UnexpectedResultException { - return RubyTypesGen.RUBYTYPES.expectRubyRange(execute(frame)); - } - - public RubyRegexp executeRubyRegexp(VirtualFrame frame) throws UnexpectedResultException { - return RubyTypesGen.RUBYTYPES.expectRubyRegexp(execute(frame)); - } - - public RubySymbol executeRubySymbol(VirtualFrame frame) throws UnexpectedResultException { - return RubyTypesGen.RUBYTYPES.expectRubySymbol(execute(frame)); - } - - public RubyThread executeRubyThread(VirtualFrame frame) throws UnexpectedResultException { - return RubyTypesGen.RUBYTYPES.expectRubyThread(execute(frame)); - } - - public RubyTime executeRubyTime(VirtualFrame frame) throws UnexpectedResultException { - return RubyTypesGen.RUBYTYPES.expectRubyTime(execute(frame)); - } - - public RubyString executeString(VirtualFrame frame) throws UnexpectedResultException { - return RubyTypesGen.RUBYTYPES.expectRubyString(execute(frame)); - } - - public UndefinedPlaceholder executeUndefinedPlaceholder(VirtualFrame frame) throws UnexpectedResultException { - return RubyTypesGen.RUBYTYPES.expectUndefinedPlaceholder(execute(frame)); - } - - public void executeVoid(VirtualFrame frame) { - execute(frame); - } - - /** - * If you aren't sure whether you have a normal {@link RubyNode} or a {@link RubyProxyNode}, - * this method will return the real node, whether that is this node, or whether this node is a - * proxy and you actually need the child. - */ - public RubyNode getNonProxyNode() { - return this; - } - - public RubyContext getContext() { - return context; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/RubyRootNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/RubyRootNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; - -/** - * The root node in an AST for a method. Unlike {@link RubyNode}, this has a single entry point, - * {@link #execute}, which Truffle knows about and can create a {@link CallTarget} from. - */ -public class RubyRootNode extends RootNode { - - protected final String indicativeName; - @Child protected RubyNode body; - - public RubyRootNode(SourceSection sourceSection, FrameDescriptor descriptor, String indicativeName, RubyNode body) { - super(sourceSection, descriptor); - - assert indicativeName != null; - assert body != null; - - this.body = adoptChild(body); - this.indicativeName = indicativeName; - } - - @Override - public Object execute(VirtualFrame frame) { - return body.execute(frame); - } - - @Override - public String toString() { - final SourceSection sourceSection = getSourceSection(); - final String source = sourceSection == null ? "" : sourceSection.toString(); - return "Method " + indicativeName + ":" + source + "@" + Integer.toHexString(hashCode()); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/RubyTypes.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/RubyTypes.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes; - -import java.math.*; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.core.array.*; -import com.oracle.truffle.ruby.runtime.core.range.*; -import com.oracle.truffle.ruby.runtime.methods.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -/** - * The list of types and type conversions that the AST interpreter knows about and can specialise - * using. Used by the DSL. - */ -@TypeSystem({UndefinedPlaceholder.class, // - NilPlaceholder.class, // - boolean.class, // - int.class, // - double.class, // - BigInteger.class, // - FixnumRange.class, // - ObjectRange.class, // - RubyArray.class, // - RubyBignum.class, // - RubyBinding.class, // - RubyClass.class, // - RubyContinuation.class, // - RubyException.class, // - RubyFiber.class, // - RubyFile.class, // - RubyFixnum.class, // - RubyFloat.class, // - RubyHash.class, // - RubyMatchData.class, // - RubyMethod.class, // - RubyModule.class, // - RubyNilClass.class, // - RubyProc.class, // - RubyRange.class, // - RubyRegexp.class, // - RubyString.class, // - RubySymbol.class, // - RubyThread.class, // - RubyTime.class, // - RubyObject.class, // - RubyBasicObject.class, // - Node.class, // - Object[].class}) -public class RubyTypes { - - /* - * The implicit casts allow the DSL to convert from an object of one type to another to satisfy - * specializations. - */ - - @ImplicitCast - public NilPlaceholder unboxNil(@SuppressWarnings("unused") RubyNilClass value) { - return NilPlaceholder.INSTANCE; - } - - @ImplicitCast - public int unboxFixnum(RubyFixnum value) { - return value.getValue(); - } - - @ImplicitCast - public BigInteger unboxBignum(RubyBignum value) { - return value.getValue(); - } - - @ImplicitCast - public double unboxFloat(RubyFloat value) { - return value.getValue(); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/WriteNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/WriteNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes; - -/** - * Interface for all nodes which write something, providing a method to transform them to read the - * same thing. - */ -public interface WriteNode { - - /** - * Return a new node that performs the equivalent read operation to this node's write. - */ - RubyNode makeReadNode(); - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/BooleanDispatchNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/BooleanDispatchNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.call; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.methods.*; - -/** - * An unboxed node in the dispatch chain that dispatches if the node is a boolean. In normal unboxed - * dispatch we look at the Java class of the receiver. However, in Ruby true and false are two - * separate classes, so in this situation we have to dispatch on the value, as well as the Java - * class when we are dealing with booleans. - *

- * TODO(CS): it would be nice if we could {@link RubyNode#executeBoolean} the receiver, but by the - * time we get to this dispatch node the receiver is already executed. - */ -public class BooleanDispatchNode extends UnboxedDispatchNode { - - private final Assumption falseUnmodifiedAssumption; - private final RubyMethod falseMethod; - - private final Assumption trueUnmodifiedAssumption; - private final RubyMethod trueMethod; - - @Child protected UnboxedDispatchNode next; - - public BooleanDispatchNode(RubyContext context, SourceSection sourceSection, Assumption falseUnmodifiedAssumption, RubyMethod falseMethod, Assumption trueUnmodifiedAssumption, - RubyMethod trueMethod, UnboxedDispatchNode next) { - super(context, sourceSection); - - assert falseUnmodifiedAssumption != null; - assert falseMethod != null; - assert trueUnmodifiedAssumption != null; - assert trueMethod != null; - - this.falseUnmodifiedAssumption = falseUnmodifiedAssumption; - this.falseMethod = falseMethod; - - this.trueUnmodifiedAssumption = trueUnmodifiedAssumption; - this.trueMethod = trueMethod; - - this.next = adoptChild(next); - } - - @Override - public Object dispatch(VirtualFrame frame, Object receiverObject, RubyProc blockObject, Object[] argumentsObjects) { - // Check it's a boolean - - if (!(receiverObject instanceof Boolean)) { - return next.dispatch(frame, receiverObject, blockObject, argumentsObjects); - } - - // Check the value - - Assumption unmodifiedAssumption; - RubyMethod method; - - if ((boolean) receiverObject) { - unmodifiedAssumption = trueUnmodifiedAssumption; - method = trueMethod; - } else { - unmodifiedAssumption = falseUnmodifiedAssumption; - method = falseMethod; - } - - // Check the class has not been modified - - try { - unmodifiedAssumption.check(); - } catch (InvalidAssumptionException e) { - return respecialize("class modified", frame, receiverObject, blockObject, argumentsObjects); - } - - // Call the method - - return method.call(frame.pack(), receiverObject, blockObject, argumentsObjects); - } - - @Override - public void setNext(UnboxedDispatchNode next) { - this.next = adoptChild(next); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/BoxedDispatchNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/BoxedDispatchNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.call; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -/** - * A node in the dispatch chain that expects the receiver to be an object boxed into a full - * {@link RubyBasicObject}. - */ -public abstract class BoxedDispatchNode extends DispatchNode { - - public BoxedDispatchNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public abstract Object dispatch(VirtualFrame frame, RubyBasicObject receiverObject, RubyProc blockObject, Object[] argumentsObjects); - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/BoxingDispatchNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/BoxingDispatchNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.call; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.utilities.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -/** - * A node in the dispatch chain that boxes the receiver into a full Ruby {@link RubyBasicObject}. - * This node is initially created as an {@link UninitializedBoxingDispatchNode} and only becomes - * this node when we know that we do need to box on the fast path. Within this node we specialized - * for the case that the receiver is always already boxed. - */ -public class BoxingDispatchNode extends UnboxedDispatchNode { - - @Child protected BoxedDispatchNode next; - - private final BranchProfile boxBranch = new BranchProfile(); - - public BoxingDispatchNode(RubyContext context, SourceSection sourceSection, BoxedDispatchNode next) { - super(context, sourceSection); - - this.next = adoptChild(next); - } - - @Override - public Object dispatch(VirtualFrame frame, Object receiverObject, RubyProc blockObject, Object[] argumentsObjects) { - RubyBasicObject boxedReceiverObject; - - if (receiverObject instanceof RubyBasicObject) { - boxedReceiverObject = (RubyBasicObject) receiverObject; - } else { - boxBranch.enter(); - boxedReceiverObject = getContext().getCoreLibrary().box(receiverObject); - } - - return next.dispatch(frame, boxedReceiverObject, blockObject, argumentsObjects); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/CachedBoxedDispatchNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/CachedBoxedDispatchNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.call; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.lookup.*; -import com.oracle.truffle.ruby.runtime.methods.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -/** - * A node in the dispatch chain that comes after the boxing point and caches a method on a full - * boxed Ruby BasicObject, matching it by looking at the lookup node and assuming it has not been - * modified. - */ -public class CachedBoxedDispatchNode extends BoxedDispatchNode { - - private final LookupNode expectedLookupNode; - private final Assumption unmodifiedAssumption; - private final RubyMethod method; - - @Child protected BoxedDispatchNode next; - - public CachedBoxedDispatchNode(RubyContext context, SourceSection sourceSection, LookupNode expectedLookupNode, RubyMethod method, BoxedDispatchNode next) { - super(context, sourceSection); - - assert expectedLookupNode != null; - assert method != null; - - this.expectedLookupNode = expectedLookupNode; - unmodifiedAssumption = expectedLookupNode.getUnmodifiedAssumption(); - this.method = method; - this.next = adoptChild(next); - } - - @Override - public Object dispatch(VirtualFrame frame, RubyBasicObject receiverObject, RubyProc blockObject, Object[] argumentsObjects) { - // Check the lookup node is what we expect - - if (receiverObject.getLookupNode() != expectedLookupNode) { - return next.dispatch(frame, receiverObject, blockObject, argumentsObjects); - } - - // Check the class has not been modified - - try { - unmodifiedAssumption.check(); - } catch (InvalidAssumptionException e) { - return respecialize("class modified", frame, receiverObject, blockObject, argumentsObjects); - } - - // Call the method - - return method.call(frame.pack(), receiverObject, blockObject, argumentsObjects); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/CachedUnboxedDispatchNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/CachedUnboxedDispatchNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.call; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.methods.*; - -/** - * A node in the dispatch chain that comes before the boxing point and caches a method on a Java - * object, matching it by looking at the class and assuming it has not been modified. - */ -public class CachedUnboxedDispatchNode extends UnboxedDispatchNode { - - private final Class expectedClass; - private final Assumption unmodifiedAssumption; - private final RubyMethod method; - - @Child protected UnboxedDispatchNode next; - - public CachedUnboxedDispatchNode(RubyContext context, SourceSection sourceSection, Class expectedClass, Assumption unmodifiedAssumption, RubyMethod method, UnboxedDispatchNode next) { - super(context, sourceSection); - - assert expectedClass != null; - assert unmodifiedAssumption != null; - assert method != null; - - this.expectedClass = expectedClass; - this.unmodifiedAssumption = unmodifiedAssumption; - this.method = method; - this.next = adoptChild(next); - } - - @Override - public Object dispatch(VirtualFrame frame, Object receiverObject, RubyProc blockObject, Object[] argumentsObjects) { - // Check the class is what we expect - - if (receiverObject.getClass() != expectedClass) { - return next.dispatch(frame, receiverObject, blockObject, argumentsObjects); - } - - // Check the class has not been modified - - try { - unmodifiedAssumption.check(); - } catch (InvalidAssumptionException e) { - return respecialize("class modified", frame, receiverObject, blockObject, argumentsObjects); - } - - // Call the method - - return method.call(frame.pack(), receiverObject, blockObject, argumentsObjects); - } - - @Override - public void setNext(UnboxedDispatchNode next) { - this.next = adoptChild(next); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/CallNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/CallNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,158 +0,0 @@ -/* - * Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.call; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.core.array.*; -import com.oracle.truffle.ruby.runtime.methods.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -/** - * A call node that has a chain of dispatch nodes. - *

- * The dispatch chain starts as {@link CallNode} -> {@link DispatchHeadNode} -> - * {@link UninitializedBoxingDispatchNode} -> {@link UninitializedDispatchNode}. - *

- * When the {@link UninitializedDispatchNode} is reached a new node is inserted into the chain. If - * the node dispatches based on some unboxed value (unboxed as in it's not a Ruby object, just a - * Java object) such as {@link Integer}, then that node is inserted before the - * {@link UninitializedBoxingDispatchNode}, otherwise if it dispatches based on some Ruby - * BasicObject, it is inserted afterwards. - *

- * The {@link UninitializedBoxingDispatchNode} becomes a {@link BoxingDispatchNode} when we find - * that the boxing has to be done on the fast path - when there is some boxed dispatch node. - *

- * So the general format is {@link CallNode} -> {@link DispatchHeadNode} -> zero or more - * unboxed dispatches -> {@link UninitializedBoxingDispatchNode} | {@link BoxingDispatchNode} - * -> zero or more boxed dispatches -> {@link UninitializedDispatchNode}. - *

- * There are several special cases of unboxed and boxed dispatch nodes based on the types and - * methods involved. - *

- * If we have too many dispatch nodes we replace the whole chain with {@link DispatchHeadNode} -> - * {@link BoxingDispatchNode} -> {@link GeneralBoxedDispatchNode}. - *

- * This system allows us to dispatch based purely on Java class, before we have to turn the object - * into a full {@link RubyBasicObject} and consider the full Ruby lookup process, and something such - * as a math call which may work on Fixnum or Float to work as just a couple of applications of - * {@code instanceof} and assumption checks. - */ -public class CallNode extends RubyNode { - - @Child protected RubyNode receiver; - @Child protected ProcOrNullNode block; - @Children protected final RubyNode[] arguments; - - private final String name; - private final boolean isSplatted; - - @Child protected DispatchHeadNode dispatchHead; - - public CallNode(RubyContext context, SourceSection section, String name, RubyNode receiver, RubyNode block, boolean isSplatted, RubyNode[] arguments) { - super(context, section); - - assert receiver != null; - assert arguments != null; - assert name != null; - - this.receiver = adoptChild(receiver); - - if (block == null) { - this.block = null; - } else { - this.block = adoptChild(ProcOrNullNodeFactory.create(context, section, block)); - } - - this.arguments = adoptChildren(arguments); - this.name = name; - this.isSplatted = isSplatted; - - dispatchHead = adoptChild(new DispatchHeadNode(context, section, name, isSplatted)); - } - - @Override - public Object execute(VirtualFrame frame) { - final Object receiverObject = receiver.execute(frame); - final Object[] argumentsObjects = executeArguments(frame); - final RubyProc blockObject = executeBlock(frame); - - return dispatchHead.dispatch(frame, receiverObject, blockObject, argumentsObjects); - } - - private RubyProc executeBlock(VirtualFrame frame) { - if (block != null) { - return block.executeRubyProc(frame); - } else { - return null; - } - } - - @ExplodeLoop - private Object[] executeArguments(VirtualFrame frame) { - final Object[] argumentsObjects = new Object[arguments.length]; - - for (int i = 0; i < arguments.length; i++) { - argumentsObjects[i] = arguments[i].execute(frame); - assert RubyContext.shouldObjectBeVisible(argumentsObjects[i]) : argumentsObjects[i].getClass(); - } - - if (isSplatted) { - assert argumentsObjects[0] instanceof RubyArray; - return ((RubyArray) argumentsObjects[0]).toObjectArray(); - } else { - return argumentsObjects; - } - } - - @Override - public Object isDefined(VirtualFrame frame) { - final RubyContext context = getContext(); - - Object receiverObject; - - try { - /* - * TODO(CS): Getting a node via an accessor like this doesn't work with Truffle at the - * moment and will cause frame escape errors, so we don't use it in compilation mode. - */ - - CompilerAsserts.neverPartOfCompilation(); - - receiverObject = receiver.execute(frame); - } catch (Exception e) { - return NilPlaceholder.INSTANCE; - } - - final RubyBasicObject receiverBasicObject = context.getCoreLibrary().box(receiverObject); - - final RubyMethod method = receiverBasicObject.getLookupNode().lookupMethod(name); - - final RubyBasicObject self = context.getCoreLibrary().box(frame.getArguments(RubyArguments.class).getSelf()); - - if (method == null || method.isUndefined()) { - return NilPlaceholder.INSTANCE; - } - - if (!method.isVisibleTo(self)) { - return NilPlaceholder.INSTANCE; - } - - return context.makeString("method"); - } - - public String getName() { - return name; - } -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/DispatchHeadNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/DispatchHeadNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.call; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.methods.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -/** - * The head of a chain of dispatch nodes. Can be used with {@link CallNode} or on its own. - */ -public class DispatchHeadNode extends DispatchNode { - - private final RubyContext context; - private final String name; - private final boolean isSplatted; - - @Child protected UnboxedDispatchNode dispatch; - - public DispatchHeadNode(RubyContext context, SourceSection sourceSection, String name, boolean isSplatted) { - super(context, sourceSection); - - assert context != null; - assert name != null; - - this.context = context; - this.name = name; - this.isSplatted = isSplatted; - - final UninitializedDispatchNode uninitializedDispatch = new UninitializedDispatchNode(context, sourceSection, name); - dispatch = adoptChild(new UninitializedBoxingDispatchNode(context, sourceSection, uninitializedDispatch)); - } - - public Object dispatch(VirtualFrame frame, Object receiverObject, RubyProc blockObject, Object... argumentsObjects) { - return dispatch.dispatch(frame, receiverObject, blockObject, argumentsObjects); - } - - /** - * Replace the entire dispatch chain with a fresh chain. Used when the situation has changed in - * such a significant way that it's best to start again rather than add new specializations to - * the chain. Used for example when methods appear to have been monkey-patched. - */ - public Object respecialize(VirtualFrame frame, String reason, Object receiverObject, RubyProc blockObject, Object... argumentObjects) { - CompilerAsserts.neverPartOfCompilation(); - - replace(new DispatchHeadNode(context, getSourceSection(), name, isSplatted), reason); - - final RubyBasicObject receiverBasicObject = context.getCoreLibrary().box(receiverObject); - - final RubyMethod method = lookup(frame, receiverBasicObject, name); - return method.call(frame.pack(), receiverBasicObject, blockObject, argumentObjects); - } - - public UnboxedDispatchNode getDispatch() { - return dispatch; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/DispatchNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/DispatchNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.call; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.control.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.methods.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -/** - * Any node in the dispatch chain. - */ -public class DispatchNode extends Node { - - private final RubyContext context; - - public DispatchNode(RubyContext context, SourceSection sourceSection) { - super(sourceSection); - - assert context != null; - assert sourceSection != null; - - this.context = context; - } - - /** - * Get the depth of this node in the dispatch chain. The first node below - * {@link DispatchHeadNode} is at depth 1. - */ - public int getDepth() { - int depth = 1; - Node parent = this.getParent(); - - while (!(parent instanceof DispatchHeadNode)) { - parent = parent.getParent(); - depth++; - } - - return depth; - } - - public Object respecialize(String reason, VirtualFrame frame, Object receiverObject, RubyProc blockObject, Object... argumentsObjects) { - CompilerAsserts.neverPartOfCompilation(); - - final int depth = getDepth(); - final DispatchHeadNode head = (DispatchHeadNode) NodeUtil.getNthParent(this, depth); - - return head.respecialize(frame, reason, receiverObject, blockObject, argumentsObjects); - } - - /** - * The central point for method lookup. - */ - protected RubyMethod lookup(VirtualFrame frame, RubyBasicObject receiverBasicObject, String name) { - final RubyMethod method = receiverBasicObject.getLookupNode().lookupMethod(name); - - final RubyBasicObject self = context.getCoreLibrary().box(frame.getArguments(RubyArguments.class).getSelf()); - - if (method == null || method.isUndefined()) { - CompilerDirectives.transferToInterpreter(); - throw new RaiseException(context.getCoreLibrary().nameErrorNoMethod(name, receiverBasicObject.toString())); - } - - if (!method.isVisibleTo(self)) { - CompilerDirectives.transferToInterpreter(); - throw new RaiseException(context.getCoreLibrary().noMethodError(name, receiverBasicObject.toString())); - } - - return method; - } - - public RubyContext getContext() { - return context; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/GeneralBoxedDispatchNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/GeneralBoxedDispatchNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.call; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.methods.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -/** - * A node in the dispatch chain that does no caching and looks up methods from scratch each time it - * is called. - */ -public class GeneralBoxedDispatchNode extends BoxedDispatchNode { - - private final String name; - - public GeneralBoxedDispatchNode(RubyContext context, SourceSection sourceSection, String name) { - super(context, sourceSection); - - assert name != null; - - this.name = name; - } - - @Override - public Object dispatch(VirtualFrame frame, RubyBasicObject receiverObject, RubyProc blockObject, Object[] argumentsObjects) { - /* - * TODO(CS): we should probably have some kind of cache here - even if it's just a hash map. - * MRI and JRuby do and might avoid some pathological cases. - */ - - final RubyMethod method = lookup(frame, receiverObject, name); - return method.call(frame.pack(), receiverObject, blockObject, argumentsObjects); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/GeneralSuperCallNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/GeneralSuperCallNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,128 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.call; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.control.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.core.array.*; -import com.oracle.truffle.ruby.runtime.methods.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -/** - * Represents a super call - that is a call with self as the receiver, but the superclass of self - * used for lookup. Currently implemented without any caching, and needs to be replaced with the - * same caching mechanism as for normal calls without complicating the existing calls too much. - */ -@NodeInfo(shortName = "general-super-call") -public class GeneralSuperCallNode extends RubyNode { - - private final String name; - private final boolean isSplatted; - @Child protected RubyNode block; - @Children protected final RubyNode[] arguments; - - public GeneralSuperCallNode(RubyContext context, SourceSection sourceSection, String name, RubyNode block, RubyNode[] arguments, boolean isSplatted) { - super(context, sourceSection); - - assert name != null; - assert arguments != null; - assert !isSplatted || arguments.length == 1; - - this.name = name; - this.block = adoptChild(block); - this.arguments = adoptChildren(arguments); - this.isSplatted = isSplatted; - } - - @ExplodeLoop - @Override - public final Object execute(VirtualFrame frame) { - // This method is only a simple implementation - it needs proper caching - - CompilerAsserts.neverPartOfCompilation(); - - final RubyBasicObject self = (RubyBasicObject) frame.getArguments(RubyArguments.class).getSelf(); - - // Execute the arguments - - final Object[] argumentsObjects = new Object[arguments.length]; - - CompilerAsserts.compilationConstant(arguments.length); - for (int i = 0; i < arguments.length; i++) { - argumentsObjects[i] = arguments[i].execute(frame); - } - - // Execute the block - - RubyProc blockObject; - - if (block != null) { - final Object blockTempObject = block.execute(frame); - - if (blockTempObject instanceof NilPlaceholder) { - blockObject = null; - } else { - blockObject = (RubyProc) blockTempObject; - } - } else { - blockObject = null; - } - - // Lookup method - - final RubyClass selfClass = self.getRubyClass(); - final RubyMethod method = selfClass.getSuperclass().lookupMethod(name); - - if (method == null || method.isUndefined()) { - CompilerDirectives.transferToInterpreter(); - throw new RaiseException(getContext().getCoreLibrary().nameErrorNoMethod(name, self.toString())); - } - - if (!method.isVisibleTo(self)) { - CompilerDirectives.transferToInterpreter(); - throw new RaiseException(getContext().getCoreLibrary().noMethodError("(unknown)")); - } - - // Call the method - - if (isSplatted) { - final RubyArray argumentsArray = (RubyArray) argumentsObjects[0]; - return method.call(frame.pack(), self, blockObject, argumentsArray.asList().toArray()); - } else { - return method.call(frame.pack(), self, blockObject, argumentsObjects); - } - } - - @Override - public Object isDefined(VirtualFrame frame) { - final RubyContext context = getContext(); - - try { - final RubyBasicObject self = context.getCoreLibrary().box(frame.getArguments(RubyArguments.class).getSelf()); - final RubyBasicObject receiverRubyObject = context.getCoreLibrary().box(self); - - final RubyMethod method = receiverRubyObject.getRubyClass().getSuperclass().lookupMethod(name); - - if (method == null || method.isUndefined() || !method.isVisibleTo(self)) { - return NilPlaceholder.INSTANCE; - } else { - return context.makeString("super"); - } - } catch (Exception e) { - return NilPlaceholder.INSTANCE; - } - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/InlineHeuristic.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/InlineHeuristic.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.call; - -import com.oracle.truffle.ruby.nodes.*; - -public class InlineHeuristic { - - public static boolean shouldInline(InlinableMethodImplementation method) { - if (method.alwaysInline()) { - return true; - } - - return false; - } - - public static boolean shouldInlineYield(@SuppressWarnings("unused") InlinableMethodImplementation method) { - return true; - } -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/InlinedBoxedDispatchNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/InlinedBoxedDispatchNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.call; - -import java.util.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.lookup.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -/** - * A node in the dispatch chain that comes after the boxing point and caches a method on a full - * boxed {@link RubyBasicObject}, matching it by looking at the lookup node and assuming it has not - * been modified. - */ -public class InlinedBoxedDispatchNode extends BoxedDispatchNode { - - private final LookupNode expectedLookupNode; - private final Assumption unmodifiedAssumption; - - private final InlinableMethodImplementation method; - private final RubyRootNode rootNode; - - @Child protected BoxedDispatchNode next; - - public InlinedBoxedDispatchNode(RubyContext context, SourceSection sourceSection, LookupNode expectedLookupNode, InlinableMethodImplementation method, BoxedDispatchNode next) { - super(context, sourceSection); - - assert expectedLookupNode != null; - assert method != null; - - this.expectedLookupNode = expectedLookupNode; - unmodifiedAssumption = expectedLookupNode.getUnmodifiedAssumption(); - this.method = method; - this.rootNode = method.getCloneOfPristineRootNode(); - this.next = adoptChild(next); - } - - @Override - public Object dispatch(VirtualFrame frame, RubyBasicObject receiverObject, RubyProc blockObject, Object[] argumentsObjects) { - // Check the lookup node is what we expect - - if (receiverObject.getLookupNode() != expectedLookupNode) { - return next.dispatch(frame, receiverObject, blockObject, argumentsObjects); - } - - // Check the class has not been modified - - try { - unmodifiedAssumption.check(); - } catch (InvalidAssumptionException e) { - return respecialize("class modified", frame, receiverObject, blockObject, argumentsObjects); - } - - // Call the method - - Object[] modifiedArgumentsObjects; - - CompilerAsserts.compilationConstant(method.getShouldAppendCallNode()); - - if (method.getShouldAppendCallNode()) { - modifiedArgumentsObjects = Arrays.copyOf(argumentsObjects, argumentsObjects.length + 1); - modifiedArgumentsObjects[modifiedArgumentsObjects.length - 1] = this; - } else { - modifiedArgumentsObjects = argumentsObjects; - } - - final RubyArguments arguments = new RubyArguments(method.getDeclarationFrame(), receiverObject, blockObject, modifiedArgumentsObjects); - final VirtualFrame inlinedFrame = Truffle.getRuntime().createVirtualFrame(frame.pack(), arguments, method.getFrameDescriptor()); - return rootNode.execute(inlinedFrame); - } -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/InlinedUnboxedDispatchNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/InlinedUnboxedDispatchNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.call; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; - -public class InlinedUnboxedDispatchNode extends UnboxedDispatchNode { - - private final Class expectedClass; - private final Assumption unmodifiedAssumption; - - private final InlinableMethodImplementation method; - private final RubyRootNode rootNode; - - @Child protected UnboxedDispatchNode next; - - public InlinedUnboxedDispatchNode(RubyContext context, SourceSection sourceSection, Class expectedClass, Assumption unmodifiedAssumption, InlinableMethodImplementation method, - UnboxedDispatchNode next) { - super(context, sourceSection); - - assert expectedClass != null; - assert method != null; - - this.expectedClass = expectedClass; - this.unmodifiedAssumption = unmodifiedAssumption; - this.method = method; - this.rootNode = method.getCloneOfPristineRootNode(); - this.next = adoptChild(next); - } - - @Override - public Object dispatch(VirtualFrame frame, Object receiverObject, RubyProc blockObject, Object[] argumentsObjects) { - // Check the class is what we expect - - if (receiverObject.getClass() != expectedClass) { - return next.dispatch(frame, receiverObject, blockObject, argumentsObjects); - } - - // Check the class has not been modified - - try { - unmodifiedAssumption.check(); - } catch (InvalidAssumptionException e) { - return respecialize("class modified", frame, receiverObject, blockObject, argumentsObjects); - } - - // Call the method - - final RubyArguments arguments = new RubyArguments(method.getDeclarationFrame(), receiverObject, blockObject, argumentsObjects); - final VirtualFrame inlinedFrame = Truffle.getRuntime().createVirtualFrame(frame.pack(), arguments, method.getFrameDescriptor()); - return rootNode.execute(inlinedFrame); - } - - @Override - public void setNext(UnboxedDispatchNode next) { - this.next = adoptChild(next); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/ProcOrNullNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/ProcOrNullNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.call; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; - -/** - * Wraps some node that will produce either a {@link RubyProc} or a {@link NilPlaceholder} and - * returns {@code null} in case of the latter. Used in parts of the dispatch chain. - */ -@NodeInfo(shortName = "proc-or-null") -@NodeChild(value = "child", type = RubyNode.class) -public abstract class ProcOrNullNode extends RubyNode { - - public ProcOrNullNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ProcOrNullNode(ProcOrNullNode prev) { - super(prev); - } - - @Specialization - public Object doNil(@SuppressWarnings("unused") NilPlaceholder nil) { - return null; - } - - @Specialization - public Object doProc(RubyProc proc) { - return proc; - } - - @Override - public RubyProc executeRubyProc(VirtualFrame frame) { - final Object proc = execute(frame); - - // The standard asRubyProc test doesn't allow for null - assert proc == null || RubyTypesGen.RUBYTYPES.isRubyProc(proc); - - return (RubyProc) proc; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/UnboxedDispatchNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/UnboxedDispatchNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.call; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -/** - * A node in the dispatch chain that expects the receiver to be a simple Java object such as a boxed - * primitive, rather than a full {@link RubyBasicObject}. This allows calls to be made with a - * receiver such as {@link Integer} without having to turn it into a {@link RubyFixnum}. Followed at - * some point by an {@link UninitializedBoxingDispatchNode} or {@link BoxingDispatchNode} before we - * try to dispatch on a Ruby BasicObject or the {@link UninitializedDispatchNode}. - */ -public abstract class UnboxedDispatchNode extends DispatchNode { - - public UnboxedDispatchNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public abstract Object dispatch(VirtualFrame frame, Object receiverObject, RubyProc blockObject, Object[] argumentsObjects); - - public void setNext(@SuppressWarnings("unused") UnboxedDispatchNode next) { - throw new UnsupportedOperationException(); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/UninitializedBoxingDispatchNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/UninitializedBoxingDispatchNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.call; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; - -/** - * A node in the dispatch chain that transfers to interpreter and then boxes the receiver. - */ -public class UninitializedBoxingDispatchNode extends UnboxedDispatchNode { - - @Child protected BoxedDispatchNode next; - - public UninitializedBoxingDispatchNode(RubyContext context, SourceSection sourceSection, BoxedDispatchNode next) { - super(context, sourceSection); - - this.next = adoptChild(next); - } - - @Override - public Object dispatch(VirtualFrame frame, Object receiverObject, RubyProc blockObject, Object[] argumentsObjects) { - CompilerDirectives.transferToInterpreter(); - - /* - * If the next dispatch node is something other than the uninitialized dispatch node then we - * need to replace this node because it's now on the fast path. If the receiver was already - * boxed. - * - * Note that with this scheme it will take a couple of calls for the chain to become fully - * specialized. - */ - - if (next instanceof UninitializedDispatchNode) { - this.replace(new BoxingDispatchNode(getContext(), getSourceSection(), next)); - } - - return next.dispatch(frame, getContext().getCoreLibrary().box(receiverObject), blockObject, argumentsObjects); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/UninitializedDispatchNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/call/UninitializedDispatchNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,127 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.call; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.methods.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -/** - * The uninitialized dispatch node. Only reached when the method is not expected by any node in the - * dispatch chain, and only creates new nodes or modifies the existing chain. - */ -public class UninitializedDispatchNode extends BoxedDispatchNode { - - /* - * Node at depth 5 is 4 actual dispatches, the boxing dispatch and the final uninitalized - * dispatch. - */ - - private static final int MAX_DEPTH = 5; - - private final String name; - - public UninitializedDispatchNode(RubyContext context, SourceSection sourceSection, String name) { - super(context, sourceSection); - - assert name != null; - - this.name = name; - } - - @Override - public Object dispatch(VirtualFrame frame, RubyBasicObject receiverObject, RubyProc blockObject, Object[] argumentsObjects) { - CompilerDirectives.transferToInterpreter(); - - final RubyContext context = getContext(); - - final RubyMethod method = lookup(frame, receiverObject, name); - - final int depth = getDepth(); - - final DispatchHeadNode dispatchHead = (DispatchHeadNode) NodeUtil.getNthParent(this, depth); - - if (depth == MAX_DEPTH) { - /* - * Replace the chain with DispatchHeadNode -> ExpectBoxedDispatchNode -> - * GeneralDispatchNode. - */ - - context.implementationMessage("resorting to a general call node at %s", getSourceSection()); - NodeUtil.printTree(System.err, dispatchHead); - - final GeneralBoxedDispatchNode newGeneralDispatch = new GeneralBoxedDispatchNode(getContext(), getSourceSection(), name); - final BoxingDispatchNode newBoxing = new BoxingDispatchNode(getContext(), getSourceSection(), newGeneralDispatch); - - dispatchHead.getDispatch().replace(newBoxing); - return newBoxing.dispatch(frame, receiverObject, blockObject, argumentsObjects); - } else if (receiverObject instanceof Unboxable) { - /* - * Unboxed dispatch nodes are prepended to the chain of dispatch nodes, so they're - * before the point where receivers will definitely be boxed. - */ - - final Object receiverUnboxed = ((Unboxable) receiverObject).unbox(); - - final UnboxedDispatchNode firstDispatch = dispatchHead.getDispatch(); - - if (receiverObject instanceof RubyTrueClass || receiverObject instanceof RubyFalseClass) { - final Assumption falseUnmodifiedAssumption = context.getCoreLibrary().getFalseClass().getUnmodifiedAssumption(); - final RubyMethod falseMethod = lookup(frame, context.getCoreLibrary().box(false), name); - final Assumption trueUnmodifiedAssumption = context.getCoreLibrary().getTrueClass().getUnmodifiedAssumption(); - final RubyMethod trueMethod = lookup(frame, context.getCoreLibrary().box(true), name); - - final BooleanDispatchNode newDispatch = new BooleanDispatchNode(getContext(), getSourceSection(), falseUnmodifiedAssumption, falseMethod, trueUnmodifiedAssumption, trueMethod, null); - firstDispatch.replace(newDispatch, "prepending new unboxed dispatch node to chain"); - newDispatch.setNext(firstDispatch); - return newDispatch.dispatch(frame, receiverUnboxed, blockObject, argumentsObjects); - } else { - UnboxedDispatchNode newDispatch; - - if (method.getImplementation() instanceof InlinableMethodImplementation && InlineHeuristic.shouldInline((InlinableMethodImplementation) method.getImplementation())) { - newDispatch = new InlinedUnboxedDispatchNode(getContext(), getSourceSection(), receiverUnboxed.getClass(), receiverObject.getRubyClass().getUnmodifiedAssumption(), - (InlinableMethodImplementation) method.getImplementation(), null); - } else { - newDispatch = new CachedUnboxedDispatchNode(getContext(), getSourceSection(), receiverUnboxed.getClass(), receiverObject.getRubyClass().getUnmodifiedAssumption(), method, null); - } - - firstDispatch.replace(newDispatch, "prepending new unboxed dispatch node to chain"); - newDispatch.setNext(firstDispatch); - - return newDispatch.dispatch(frame, receiverUnboxed, blockObject, argumentsObjects); - } - } else { - /* - * Boxed dispatch nodes are appended to the chain of dispatch nodes, so they're after - * the point where receivers are guaranteed to be boxed. - */ - - final UninitializedDispatchNode newUninitializedDispatch = new UninitializedDispatchNode(getContext(), getSourceSection(), name); - - BoxedDispatchNode newDispatch; - - if (method.getImplementation() instanceof InlinableMethodImplementation && InlineHeuristic.shouldInline((InlinableMethodImplementation) method.getImplementation())) { - newDispatch = new InlinedBoxedDispatchNode(getContext(), getSourceSection(), receiverObject.getLookupNode(), (InlinableMethodImplementation) method.getImplementation(), - newUninitializedDispatch); - } else { - newDispatch = new CachedBoxedDispatchNode(getContext(), getSourceSection(), receiverObject.getLookupNode(), method, newUninitializedDispatch); - } - - replace(newDispatch, "appending new boxed dispatch node to chain"); - - return newDispatch.dispatch(frame, receiverObject, blockObject, argumentsObjects); - } - } -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/cast/BooleanCastNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/cast/BooleanCastNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.cast; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; - -/** - * Casts a value into a boolean. Works at the language level, so doesn't call any Ruby methods to - * cast non-core or monkey-patched objects. - */ -@NodeInfo(shortName = "cast-boolean") -@NodeChild(value = "child", type = RubyNode.class) -public abstract class BooleanCastNode extends RubyNode { - - public BooleanCastNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public BooleanCastNode(BooleanCastNode copy) { - super(copy.getContext(), copy.getSourceSection()); - } - - @Specialization - public boolean doBoolean(boolean value) { - return value; - } - - @Specialization - public boolean doNil(@SuppressWarnings("unused") NilPlaceholder nil) { - return false; - } - - @Generic - public boolean doGeneric(Object object) { - if (object instanceof Boolean) { - return (boolean) object; - } else if (object instanceof NilPlaceholder || object instanceof RubyNilClass) { - return false; - } else { - return true; - } - } - - @Override - public abstract boolean executeBoolean(VirtualFrame frame); - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/cast/LambdaNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/cast/LambdaNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.cast; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.methods.*; - -@NodeInfo(shortName = "lambda") -public class LambdaNode extends RubyNode { - - @Child private RubyNode definition; - - public LambdaNode(RubyContext context, SourceSection sourceSection, RubyNode definition) { - super(context, sourceSection); - this.definition = adoptChild(definition); - } - - @Override - public Object execute(VirtualFrame frame) { - return new RubyProc(getContext().getCoreLibrary().getProcClass(), RubyProc.Type.LAMBDA, frame.getArguments(RubyArguments.class).getSelf(), null, (RubyMethod) definition.execute(frame)); - } - - @Override - public void executeVoid(VirtualFrame frame) { - definition.executeVoid(frame); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/cast/ProcCastNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/cast/ProcCastNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.cast; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.nodes.call.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -/** - * Casts an object to a Ruby Proc object. - */ -@NodeInfo(shortName = "cast-proc") -@NodeChild("child") -public abstract class ProcCastNode extends RubyNode { - - @Child protected DispatchHeadNode toProc; - - public ProcCastNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - toProc = adoptChild(new DispatchHeadNode(context, getSourceSection(), "to_proc", false)); - } - - public ProcCastNode(ProcCastNode prev) { - super(prev); - toProc = adoptChild(prev.toProc); - } - - @Specialization - public NilPlaceholder doNil(NilPlaceholder nil) { - return nil; - } - - @Specialization - public RubyProc doRubyProc(RubyProc proc) { - return proc; - } - - @Specialization - public RubyProc doObject(VirtualFrame frame, RubyBasicObject object) { - return (RubyProc) toProc.dispatch(frame, object, null); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/cast/SplatCastNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/cast/SplatCastNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.cast; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.array.*; - -/** - * Splat as used to cast a value to an array if it isn't already, as in {@code *value}. - */ -@NodeInfo(shortName = "cast-splat") -@NodeChild("child") -public abstract class SplatCastNode extends RubyNode { - - public SplatCastNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public SplatCastNode(SplatCastNode prev) { - super(prev); - } - - protected abstract RubyNode getChild(); - - @Specialization - public RubyArray doArray(RubyArray array) { - return array; - } - - @Specialization - public RubyArray doObject(Object object) { - if (object instanceof RubyArray) { - return (RubyArray) object; - } else { - return RubyArray.specializedFromObject(getContext().getCoreLibrary().getArrayClass(), object); - } - } - - @Override - public void executeVoid(VirtualFrame frame) { - getChild().executeVoid(frame); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/cast/StringToRegexpNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/cast/StringToRegexpNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.cast; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; - -/** - * Creates a regex from a string. - */ -@NodeInfo(shortName = "cast-string-to-regexp") -@NodeChild("string") -public abstract class StringToRegexpNode extends RubyNode { - - public StringToRegexpNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public StringToRegexpNode(StringToRegexpNode prev) { - super(prev); - } - - @Specialization - public RubyRegexp doString(RubyString string) { - return new RubyRegexp(getContext().getCoreLibrary().getRegexpClass(), string.toString()); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/cast/StringToSymbolNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/cast/StringToSymbolNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.cast; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; - -/** - * Creates a symbol from a string. - */ -@NodeInfo(shortName = "cast-string-to-symbol") -@NodeChild("string") -public abstract class StringToSymbolNode extends RubyNode { - - public StringToSymbolNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public StringToSymbolNode(StringToSymbolNode prev) { - super(prev); - } - - @Specialization - public RubySymbol doString(RubyString string) { - return new RubySymbol(getContext().getCoreLibrary().getSymbolClass(), string.toString()); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/constants/CachedReadConstantNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/constants/CachedReadConstantNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,177 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.constants; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.utilities.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -/** - * Represents a constant read from some object and cached, with the assumption that the object it - * was read from is unmodified. If that assumption does not hold the read is uninitialized. If the - * class of the receiver changes we also uninitialize. - */ -@NodeInfo(shortName = "cached-read-constant") -public class CachedReadConstantNode extends ReadConstantNode { - - private final RubyClass expectedClass; - private final Assumption unmodifiedAssumption; - - private final Object value; - - private final boolean hasBoolean; - private final boolean booleanValue; - - private final boolean hasInt; - private final int intValue; - - private final boolean hasDouble; - private final double doubleValue; - - private final BranchProfile boxBranchProfile = new BranchProfile(); - - public CachedReadConstantNode(RubyContext context, SourceSection sourceSection, String name, RubyNode receiver, RubyClass expectedClass, Object value) { - super(context, sourceSection, name, receiver); - - this.expectedClass = expectedClass; - unmodifiedAssumption = expectedClass.getUnmodifiedAssumption(); - - this.value = value; - - /* - * We could do this lazily as needed, but I'm sure the compiler will appreciate the fact - * that these fields are all final. - */ - - if (value instanceof Boolean) { - hasBoolean = true; - booleanValue = (boolean) value; - - hasInt = false; - intValue = -1; - - hasDouble = false; - doubleValue = -1; - } else if (value instanceof Integer) { - hasBoolean = false; - booleanValue = false; - - hasInt = true; - intValue = (int) value; - - hasDouble = true; - doubleValue = (int) value; - } else if (value instanceof Double) { - hasBoolean = false; - booleanValue = false; - - hasInt = false; - intValue = -1; - - hasDouble = true; - doubleValue = (double) value; - } else { - hasBoolean = false; - booleanValue = false; - - hasInt = false; - intValue = -1; - - hasDouble = false; - doubleValue = -1; - } - } - - @Override - public Object execute(VirtualFrame frame) { - try { - guard(frame); - } catch (UnexpectedResultException e) { - return e.getResult(); - } - - return value; - } - - @Override - public boolean executeBoolean(VirtualFrame frame) throws UnexpectedResultException { - guard(frame); - - if (hasBoolean) { - return booleanValue; - } else { - throw new UnexpectedResultException(value); - } - } - - @Override - public int executeFixnum(VirtualFrame frame) throws UnexpectedResultException { - guard(frame); - - if (hasInt) { - return intValue; - } else { - throw new UnexpectedResultException(value); - } - } - - @Override - public double executeFloat(VirtualFrame frame) throws UnexpectedResultException { - guard(frame); - - if (hasDouble) { - return doubleValue; - } else { - throw new UnexpectedResultException(value); - } - } - - @Override - public void executeVoid(VirtualFrame frame) { - } - - public void guard(VirtualFrame frame) throws UnexpectedResultException { - final RubyContext context = getContext(); - - final Object receiverObject = receiver.execute(frame); - - RubyBasicObject receiverRubyObject; - - // TODO(CS): put the boxing into a separate node that can specialize for each type it sees - - if (receiverObject instanceof RubyBasicObject) { - receiverRubyObject = (RubyBasicObject) receiverObject; - } else { - boxBranchProfile.enter(); - receiverRubyObject = context.getCoreLibrary().box(receiverObject); - } - - if (receiverRubyObject.getRubyClass() != expectedClass) { - CompilerDirectives.transferToInterpreter(); - throw new UnexpectedResultException(uninitialize(receiverRubyObject)); - } - - try { - unmodifiedAssumption.check(); - } catch (InvalidAssumptionException e) { - throw new UnexpectedResultException(uninitialize(receiverRubyObject)); - } - } - - private Object uninitialize(RubyBasicObject receiverObject) { - return replace(new UninitializedReadConstantNode(getContext(), getSourceSection(), name, receiver)).execute(receiverObject); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/constants/ReadConstantNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/constants/ReadConstantNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.constants; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.control.*; - -public abstract class ReadConstantNode extends RubyNode { - - protected final String name; - @Child protected RubyNode receiver; - - public ReadConstantNode(RubyContext context, SourceSection sourceSection, String name, RubyNode receiver) { - super(context, sourceSection); - this.name = name; - this.receiver = adoptChild(receiver); - } - - @Override - public Object isDefined(VirtualFrame frame) { - final RubyContext context = getContext(); - - if (name.equals("Encoding")) { - /* - * Work-around so I don't have to load the iconv library - runners/formatters/junit.rb. - */ - return context.makeString("constant"); - } - - Object value; - - try { - value = context.getCoreLibrary().box(receiver.execute(frame)).getLookupNode().lookupConstant(name); - } catch (RaiseException e) { - /* - * If we are looking up a constant in a constant that is itself undefined, we return Nil - * rather than raising the error. Eg.. defined?(Defined::Undefined1::Undefined2) - */ - - if (e.getRubyException().getRubyClass() == context.getCoreLibrary().getNameErrorClass()) { - return NilPlaceholder.INSTANCE; - } - - throw e; - } - - if (value == null) { - return NilPlaceholder.INSTANCE; - } else { - return context.makeString("constant"); - } - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/constants/UninitializedReadConstantNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/constants/UninitializedReadConstantNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.constants; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.control.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -/** - * Represents an uninitialized constant read from some object. After the first read it will be - * specialized to some other node. This is the starting point for all constant reads. - */ -@NodeInfo(shortName = "uninitialized-read-constant") -public class UninitializedReadConstantNode extends ReadConstantNode { - - public UninitializedReadConstantNode(RubyContext context, SourceSection sourceSection, String name, RubyNode receiver) { - super(context, sourceSection, name, receiver); - } - - /** - * This execute method allows us to pass in the already executed receiver object, so that during - * uninitialization it is not executed once by the specialized node and again by this node. - */ - public Object execute(RubyBasicObject receiverObject) { - CompilerAsserts.neverPartOfCompilation(); - - final RubyContext context = receiverObject.getRubyClass().getContext(); - - Object value; - - value = receiverObject.getLookupNode().lookupConstant(name); - - if (value == null && receiverObject instanceof RubyModule) { - /* - * FIXME(CS): I'm obviously doing something wrong with constant lookup in nested modules - * here, but explicitly looking in the Module itself, not its lookup node, seems to fix - * it for now. - */ - - value = ((RubyModule) receiverObject).lookupConstant(name); - } - - if (value == null) { - throw new RaiseException(context.getCoreLibrary().nameErrorUninitializedConstant(name)); - } - - replace(new CachedReadConstantNode(context, getSourceSection(), name, receiver, receiverObject.getRubyClass(), value)); - - assert RubyContext.shouldObjectBeVisible(value); - - return value; - } - - @Override - public Object execute(VirtualFrame frame) { - CompilerDirectives.transferToInterpreter(); - - final RubyContext context = getContext(); - - final Object receiverObject = receiver.execute(frame); - final RubyBasicObject receiverRubyObject = context.getCoreLibrary().box(receiverObject); - - return execute(receiverRubyObject); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/constants/WriteConstantNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/constants/WriteConstantNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.constants; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; - -/** - * Represents writing a constant into some module. - */ -@NodeInfo(shortName = "write-constant") -public class WriteConstantNode extends RubyNode { - - private final String name; - @Child protected RubyNode module; - @Child protected RubyNode rhs; - - public WriteConstantNode(RubyContext context, SourceSection sourceSection, String name, RubyNode module, RubyNode rhs) { - super(context, sourceSection); - this.name = name; - this.module = adoptChild(module); - this.rhs = adoptChild(rhs); - } - - @Override - public Object execute(VirtualFrame frame) { - // TODO(cs): can module ever not evaluate to a RubyModule? - - final RubyModule moduleObject = (RubyModule) module.execute(frame); - - final Object rhsValue = rhs.execute(frame); - - assert rhsValue != null; - assert !(rhsValue instanceof String); - - moduleObject.setModuleConstant(name, rhsValue); - - return rhsValue; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/AndNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/AndNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.control; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; - -/** - * Represents a Ruby {@code and} or {@code &&} expression. - */ -@NodeInfo(shortName = "and") -@NodeChildren({@NodeChild("left"), @NodeChild("right")}) -public abstract class AndNode extends RubyNode { - - public AndNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public AndNode(AndNode copy) { - super(copy.getContext(), copy.getSourceSection()); - } - - @ShortCircuit("right") - public boolean needsRightNode(Object a) { - return GeneralConversions.toBoolean(a); - } - - @ShortCircuit("right") - public boolean needsRightNode(boolean a) { - return a; - } - - @Specialization - public boolean doBoolean(boolean a, boolean hasB, boolean b) { - return hasB ? b : a; - } - - @Specialization - public Object doObject(boolean a, boolean hasB, Object b) { - return hasB ? b : a; - } - - @Generic - public Object doGeneric(Object a, boolean hasB, Object b) { - return hasB ? b : a; - } -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/BreakNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/BreakNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.control; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.nodes.literal.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.control.*; - -@NodeInfo(shortName = "break") -public class BreakNode extends RubyNode { - - @Child private RubyNode child; - - public BreakNode(RubyContext context, SourceSection sourceSection, RubyNode child) { - super(context, sourceSection); - this.child = adoptChild(child); - } - - @Override - public Object execute(VirtualFrame frame) { - if (child instanceof NilNode) { - throw BreakException.NIL; - } else { - throw new BreakException(child.execute(frame)); - } - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/ElidableResultNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/ElidableResultNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.control; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; - -/** - * This node has a pair of children - one required and one elidable result. The required node is - * always executed, but its result is discarded. Therefore it should perform some useful side - * effects. The elidable node is executed, and its result value returned, if an execute method with - * a non-void type is used. It is not executed at all if a void typed execute method is used. - * Therefore it should not perform any observable side effects. - */ -@NodeInfo(shortName = "elidable-result") -public class ElidableResultNode extends RubyNode { - - @Child protected RubyNode required; - @Child protected RubyNode elidableResult; - - public ElidableResultNode(RubyContext context, SourceSection sourceSection, RubyNode required, RubyNode elidableResult) { - super(context, sourceSection); - this.required = adoptChild(required); - this.elidableResult = adoptChild(elidableResult); - } - - @Override - public int executeFixnum(VirtualFrame frame) throws UnexpectedResultException { - required.executeVoid(frame); - return elidableResult.executeFixnum(frame); - } - - @Override - public double executeFloat(VirtualFrame frame) throws UnexpectedResultException { - required.executeVoid(frame); - return elidableResult.executeFloat(frame); - } - - @Override - public Object execute(VirtualFrame frame) { - required.executeVoid(frame); - return elidableResult.execute(frame); - } - - @Override - public void executeVoid(VirtualFrame frame) { - required.execute(frame); - } - - @Override - public Object isDefined(VirtualFrame frame) { - return elidableResult.isDefined(frame); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/EnsureNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/EnsureNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.control; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; - -/** - * Represents an ensure clause in exception handling. Represented separately to the try part. - */ -@NodeInfo(shortName = "ensure") -public class EnsureNode extends RubyNode { - - @Child protected RubyNode tryPart; - @Child protected RubyNode ensurePart; - - public EnsureNode(RubyContext context, SourceSection sourceSection, RubyNode tryPart, RubyNode ensurePart) { - super(context, sourceSection); - this.tryPart = adoptChild(tryPart); - this.ensurePart = adoptChild(ensurePart); - } - - @Override - public Object execute(VirtualFrame frame) { - try { - return tryPart.execute(frame); - } finally { - ensurePart.executeVoid(frame); - } - } - - @Override - public void executeVoid(VirtualFrame frame) { - try { - tryPart.executeVoid(frame); - } finally { - ensurePart.executeVoid(frame); - } - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/FlipFlopNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/FlipFlopNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.control; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.nodes.cast.*; -import com.oracle.truffle.ruby.nodes.methods.locals.*; -import com.oracle.truffle.ruby.runtime.*; - -@NodeInfo(shortName = "flip-flop") -public class FlipFlopNode extends RubyNode { - - @Child protected BooleanCastNode begin; - @Child protected BooleanCastNode end; - @Child protected FlipFlopStateNode stateNode; - - private final boolean exclusive; - - public FlipFlopNode(RubyContext context, SourceSection sourceSection, BooleanCastNode begin, BooleanCastNode end, FlipFlopStateNode stateNode, boolean exclusive) { - super(context, sourceSection); - this.begin = adoptChild(begin); - this.end = adoptChild(end); - this.stateNode = adoptChild(stateNode); - this.exclusive = exclusive; - } - - @Override - public boolean executeBoolean(VirtualFrame frame) { - if (exclusive) { - if (stateNode.getState(frame)) { - if (end.executeBoolean(frame)) { - stateNode.setState(frame, false); - } - - return true; - } else { - final boolean newState = begin.executeBoolean(frame); - stateNode.setState(frame, newState); - return newState; - } - } else { - if (stateNode.getState(frame)) { - if (end.executeBoolean(frame)) { - stateNode.setState(frame, false); - } - - return true; - } else { - if (begin.executeBoolean(frame)) { - stateNode.setState(frame, !end.executeBoolean(frame)); - return true; - } - - return false; - } - } - } - - @Override - public Object execute(VirtualFrame frame) { - return executeBoolean(frame); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/IfNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/IfNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.control; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.utilities.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.nodes.cast.*; -import com.oracle.truffle.ruby.runtime.*; - -/** - * Represents a Ruby {@code if} expression. Note that in this representation we always have an - * {@code else} part. - */ -@NodeInfo(shortName = "if") -public class IfNode extends RubyNode { - - @Child protected BooleanCastNode condition; - @Child protected RubyNode thenBody; - @Child protected RubyNode elseBody; - - private final BranchProfile thenProfile = new BranchProfile(); - private final BranchProfile elseProfile = new BranchProfile(); - - public IfNode(RubyContext context, SourceSection sourceSection, BooleanCastNode condition, RubyNode thenBody, RubyNode elseBody) { - super(context, sourceSection); - this.condition = adoptChild(condition); - this.thenBody = adoptChild(thenBody); - this.elseBody = adoptChild(elseBody); - } - - @Override - public Object execute(VirtualFrame frame) { - if (condition.executeBoolean(frame)) { - thenProfile.enter(); - return thenBody.execute(frame); - } else { - elseProfile.enter(); - return elseBody.execute(frame); - } - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/NextNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/NextNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.control; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.nodes.literal.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.control.*; - -@NodeInfo(shortName = "next") -public class NextNode extends RubyNode { - - @Child private RubyNode child; - - public NextNode(RubyContext context, SourceSection sourceSection, RubyNode child) { - super(context, sourceSection); - - this.child = adoptChild(child); - } - - @Override - public Object execute(VirtualFrame frame) { - if (child instanceof NilNode) { - throw NextException.NIL; - } else { - throw new NextException(child.execute(frame)); - } - } -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/NotNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/NotNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.control; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.nodes.cast.*; -import com.oracle.truffle.ruby.runtime.*; - -/** - * Represents a Ruby {@code not} or {@code !} expression. - */ -@NodeInfo(shortName = "not") -public class NotNode extends RubyNode { - - @Child protected BooleanCastNode child; - - public NotNode(RubyContext context, SourceSection sourceSection, BooleanCastNode child) { - super(context, sourceSection); - this.child = adoptChild(child); - } - - @Override - public boolean executeBoolean(VirtualFrame frame) { - return !child.executeBoolean(frame); - } - - @Override - public Object execute(VirtualFrame frame) { - return executeBoolean(frame); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/OrNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/OrNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.control; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; - -/** - * Represents a Ruby {@code or} or {@code ||} expression. - */ -@NodeInfo(shortName = "or") -@NodeChildren({@NodeChild("left"), @NodeChild("right")}) -public abstract class OrNode extends RubyNode { - - public OrNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public OrNode(OrNode copy) { - super(copy.getContext(), copy.getSourceSection()); - } - - @ShortCircuit("right") - public boolean needsRightNode(Object a) { - return !GeneralConversions.toBoolean(a); - } - - @ShortCircuit("right") - public boolean needsRightNode(boolean a) { - return !a; - } - - @Specialization - public Object doBoolean(boolean a, boolean hasB, Object b) { - return hasB ? b : a; - } - - @Generic - public Object doGeneric(Object a, boolean hasB, Object b) { - return hasB ? b : a; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/RedoNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/RedoNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.control; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.control.*; - -@NodeInfo(shortName = "redo") -public class RedoNode extends RubyNode { - - public RedoNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - @Override - public Object execute(VirtualFrame frame) { - throw new RedoException(); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/RescueAnyNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/RescueAnyNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.control; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -/** - * Rescues any exception. - */ -@NodeInfo(shortName = "rescue-any") -public class RescueAnyNode extends RescueNode { - - public RescueAnyNode(RubyContext context, SourceSection sourceSection, RubyNode body) { - super(context, sourceSection, body); - } - - @Override - public boolean canHandle(VirtualFrame frame, RubyBasicObject exception) { - return true; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/RescueClassesNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/RescueClassesNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.control; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -/** - * Rescues any of a set of classes. - */ -@NodeInfo(shortName = "rescue-classes") -public class RescueClassesNode extends RescueNode { - - @Children final RubyNode[] handlingClassNodes; - - public RescueClassesNode(RubyContext context, SourceSection sourceSection, RubyNode[] handlingClassNodes, RubyNode body) { - super(context, sourceSection, body); - this.handlingClassNodes = adoptChildren(handlingClassNodes); - } - - @ExplodeLoop - @Override - public boolean canHandle(VirtualFrame frame, RubyBasicObject exception) { - final RubyClass exceptionRubyClass = exception.getRubyClass(); - - for (RubyNode handlingClassNode : handlingClassNodes) { - // TODO(CS): what if we don't get a class? - - final RubyClass handlingClass = (RubyClass) handlingClassNode.execute(frame); - - if (exceptionRubyClass.assignableTo(handlingClass)) { - return true; - } - } - - return false; - } -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/RescueNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/RescueNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.control; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -/** - * Base node for all nodes which may be able to rescue an exception. They have a test method - * {@link #canHandle} and a body to execute if that test passes. - */ -public abstract class RescueNode extends RubyNode { - - @Child protected RubyNode body; - - public RescueNode(RubyContext context, SourceSection sourceSection, RubyNode body) { - super(context, sourceSection); - this.body = adoptChild(body); - } - - public abstract boolean canHandle(VirtualFrame frame, RubyBasicObject exception); - - @Override - public Object execute(VirtualFrame frame) { - return body.execute(frame); - } - - @Override - public void executeVoid(VirtualFrame frame) { - body.executeVoid(frame); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/RescueSplatNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/RescueSplatNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.control; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.core.array.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -/** - * Rescue any of several classes, that we get from an expression that evaluates to an array of - * classes. - * - */ -@NodeInfo(shortName = "rescue-splat") -public class RescueSplatNode extends RescueNode { - - @Child RubyNode handlingClassesArray; - - public RescueSplatNode(RubyContext context, SourceSection sourceSection, RubyNode handlingClassesArray, RubyNode body) { - super(context, sourceSection, body); - this.handlingClassesArray = adoptChild(handlingClassesArray); - } - - @ExplodeLoop - @Override - public boolean canHandle(VirtualFrame frame, RubyBasicObject exception) { - final RubyArray handlingClasses = (RubyArray) handlingClassesArray.execute(frame); - - final RubyClass exceptionRubyClass = exception.getRubyClass(); - - for (Object handlingClass : handlingClasses.asList()) { - if (exceptionRubyClass.assignableTo((RubyClass) handlingClass)) { - return true; - } - } - - return false; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/RetryNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/RetryNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.control; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.control.*; - -@NodeInfo(shortName = "retry") -public class RetryNode extends RubyNode { - - public RetryNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - @Override - public Object execute(VirtualFrame frame) { - throw new RetryException(); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/ReturnNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/ReturnNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.control; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.control.*; - -/** - * Represents an explicit return. The return ID indicates where we should be returning to - this can - * be non-trivial if you have blocks. - */ -@NodeInfo(shortName = "return") -public class ReturnNode extends RubyNode { - - private final long returnID; - @Child protected RubyNode value; - - public ReturnNode(RubyContext context, SourceSection sourceSection, long returnID, RubyNode value) { - super(context, sourceSection); - this.returnID = returnID; - this.value = adoptChild(value); - } - - @Override - public Object execute(VirtualFrame frame) { - throw new ReturnException(returnID, value.execute(frame)); - } -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/SequenceNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/SequenceNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.control; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; - -/** - * A sequence of statements to be executed in serial. - */ -@NodeInfo(shortName = "sequence") -public final class SequenceNode extends RubyNode { - - @Children protected final RubyNode[] body; - - public SequenceNode(RubyContext context, SourceSection sourceSection, RubyNode... body) { - super(context, sourceSection); - this.body = adoptChildren(body); - } - - @ExplodeLoop - @Override - public Object execute(VirtualFrame frame) { - for (int n = 0; n < body.length - 1; n++) { - body[n].executeVoid(frame); - } - - return body[body.length - 1].execute(frame); - } - - @ExplodeLoop - @Override - public void executeVoid(VirtualFrame frame) { - for (int n = 0; n < body.length; n++) { - body[n].executeVoid(frame); - } - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/TryNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/TryNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.control; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.utilities.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.control.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -/** - * Represents a block of code run with exception handlers. There's no {@code try} keyword in Ruby - - * it's implicit - but it's similar to a try statement in any other language. - */ -@NodeInfo(shortName = "try") -public class TryNode extends RubyNode { - - @Child protected RubyNode tryPart; - @Children final RescueNode[] rescueParts; - @Child protected RubyNode elsePart; - - private final BranchProfile controlFlowProfile = new BranchProfile(); - - public TryNode(RubyContext context, SourceSection sourceSection, RubyNode tryPart, RescueNode[] rescueParts, RubyNode elsePart) { - super(context, sourceSection); - this.tryPart = adoptChild(tryPart); - this.rescueParts = adoptChildren(rescueParts); - this.elsePart = adoptChild(elsePart); - } - - @Override - public Object execute(VirtualFrame frame) { - while (true) { - try { - final Object result = tryPart.execute(frame); - elsePart.executeVoid(frame); - return result; - } catch (ControlFlowException exception) { - controlFlowProfile.enter(); - - throw exception; - } catch (RuntimeException exception) { - CompilerDirectives.transferToInterpreter(); - - try { - return handleException(frame, exception); - } catch (RetryException e) { - continue; - } - } - } - } - - private Object handleException(VirtualFrame frame, RuntimeException exception) { - CompilerAsserts.neverPartOfCompilation(); - - final RubyContext context = getContext(); - - final RubyBasicObject rubyException = ExceptionTranslator.translateException(context, exception); - - context.getCoreLibrary().getGlobalVariablesObject().setInstanceVariable("$!", rubyException); - - for (RescueNode rescue : rescueParts) { - if (rescue.canHandle(frame, rubyException)) { - return rescue.execute(frame); - } - } - - throw exception; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/WhileNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/control/WhileNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.control; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.utilities.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.nodes.cast.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.control.*; - -/** - * Represents a Ruby {@code while} statement. - */ -@NodeInfo(shortName = "while") -public class WhileNode extends RubyNode { - - @Child protected BooleanCastNode condition; - @Child protected RubyNode body; - - private final BranchProfile breakProfile = new BranchProfile(); - private final BranchProfile nextProfile = new BranchProfile(); - private final BranchProfile redoProfile = new BranchProfile(); - - public WhileNode(RubyContext context, SourceSection sourceSection, BooleanCastNode condition, RubyNode body) { - super(context, sourceSection); - this.condition = adoptChild(condition); - this.body = adoptChild(body); - } - - @Override - public Object execute(VirtualFrame frame) { - outer: while (condition.executeBoolean(frame)) { - while (true) { - try { - body.execute(frame); - continue outer; - } catch (BreakException e) { - breakProfile.enter(); - return e.getResult(); - } catch (NextException e) { - nextProfile.enter(); - continue outer; - } catch (RedoException e) { - redoProfile.enter(); - } - } - } - - return NilPlaceholder.INSTANCE; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ArrayConcatNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ArrayConcatNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.core; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.array.*; - -/** - * Concatenate arrays. - */ -@NodeInfo(shortName = "array-concat") -public final class ArrayConcatNode extends RubyNode { - - @Children protected final RubyNode[] children; - - public ArrayConcatNode(RubyContext context, SourceSection sourceSection, RubyNode[] children) { - super(context, sourceSection); - assert children.length > 1; - this.children = adoptChildren(children); - } - - @ExplodeLoop - @Override - public Object execute(VirtualFrame frame) { - final RubyArray array = new RubyArray(getContext().getCoreLibrary().getArrayClass()); - - for (int n = 0; n < children.length; n++) { - final Object childObject = children[n].execute(frame); - - if (childObject instanceof RubyArray) { - // setRangeArray has special cases for setting a zero-length range at the end - final int end = array.size(); - array.setRangeArrayExclusive(end, end, (RubyArray) childObject); - } else { - array.push(childObject); - } - } - - return array; - } - - @ExplodeLoop - @Override - public void executeVoid(VirtualFrame frame) { - for (int n = 0; n < children.length; n++) { - children[n].executeVoid(frame); - } - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ArrayCoreMethodNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ArrayCoreMethodNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.core; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.array.*; - -public abstract class ArrayCoreMethodNode extends CoreMethodNode { - - public ArrayCoreMethodNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ArrayCoreMethodNode(ArrayCoreMethodNode prev) { - super(prev); - } - - protected boolean isEmptyStore(RubyArray receiver) { - return receiver.getArrayStore() instanceof EmptyArrayStore; - } - - protected boolean isFixnumStore(RubyArray receiver) { - return receiver.getArrayStore() instanceof FixnumArrayStore; - } - - protected boolean isFixnumImmutablePairStore(RubyArray receiver) { - return receiver.getArrayStore() instanceof FixnumImmutablePairArrayStore; - } - - protected boolean isObjectStore(RubyArray receiver) { - return receiver.getArrayStore() instanceof ObjectArrayStore; - } - - protected boolean isObjectImmutablePairStore(RubyArray receiver) { - return receiver.getArrayStore() instanceof ObjectImmutablePairArrayStore; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ArrayIndexNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ArrayIndexNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,110 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.core; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.array.*; - -/** - * Index an array, without using any method lookup. This isn't a call - it's an operation on a core - * class. - */ -@NodeInfo(shortName = "array-index") -@NodeChildren({@NodeChild(value = "array", type = RubyNode.class)}) -public abstract class ArrayIndexNode extends RubyNode { - - final int index; - - public ArrayIndexNode(RubyContext context, SourceSection sourceSection, int index) { - super(context, sourceSection); - this.index = index; - } - - public ArrayIndexNode(ArrayIndexNode prev) { - super(prev); - index = prev.index; - } - - @Specialization(guards = "isEmptyStore", order = 1) - public NilPlaceholder indexEmpty(@SuppressWarnings("unused") RubyArray array) { - return NilPlaceholder.INSTANCE; - } - - @Specialization(guards = "isFixnumStore", rewriteOn = UnexpectedResultException.class, order = 2) - public int indexFixnum(RubyArray array) throws UnexpectedResultException { - final FixnumArrayStore store = (FixnumArrayStore) array.getArrayStore(); - return store.getFixnum(ArrayUtilities.normaliseIndex(store.size(), index)); - } - - @Specialization(guards = "isFixnumStore", order = 3) - public Object indexMaybeFixnum(RubyArray array) { - final FixnumArrayStore store = (FixnumArrayStore) array.getArrayStore(); - - try { - return store.getFixnum(ArrayUtilities.normaliseIndex(store.size(), index)); - } catch (UnexpectedResultException e) { - return e.getResult(); - } - } - - @Specialization(guards = "isFixnumImmutablePairStore", rewriteOn = UnexpectedResultException.class, order = 4) - public int indexFixnumImmutablePair(RubyArray array) throws UnexpectedResultException { - final FixnumImmutablePairArrayStore store = (FixnumImmutablePairArrayStore) array.getArrayStore(); - return store.getFixnum(ArrayUtilities.normaliseIndex(store.size(), index)); - } - - @Specialization(guards = "isFixnumImmutablePairStore", order = 5) - public Object indexMaybeFixnumImmutablePair(RubyArray array) { - final FixnumImmutablePairArrayStore store = (FixnumImmutablePairArrayStore) array.getArrayStore(); - - try { - return store.getFixnum(ArrayUtilities.normaliseIndex(store.size(), index)); - } catch (UnexpectedResultException e) { - return e.getResult(); - } - } - - @Specialization(guards = "isObjectStore", order = 6) - public Object indexObject(RubyArray array) { - final ObjectArrayStore store = (ObjectArrayStore) array.getArrayStore(); - return store.get(ArrayUtilities.normaliseIndex(store.size(), index)); - } - - @Specialization(guards = "isObjectImmutablePairStore", order = 7) - public Object indexObjectImmutablePair(RubyArray array) { - final ObjectImmutablePairArrayStore store = (ObjectImmutablePairArrayStore) array.getArrayStore(); - return store.get(ArrayUtilities.normaliseIndex(store.size(), index)); - } - - protected boolean isEmptyStore(RubyArray receiver) { - return receiver.getArrayStore() instanceof EmptyArrayStore; - } - - protected boolean isFixnumStore(RubyArray receiver) { - return receiver.getArrayStore() instanceof FixnumArrayStore; - } - - protected boolean isFixnumImmutablePairStore(RubyArray receiver) { - return receiver.getArrayStore() instanceof FixnumImmutablePairArrayStore; - } - - protected boolean isObjectStore(RubyArray receiver) { - return receiver.getArrayStore() instanceof ObjectArrayStore; - } - - protected boolean isObjectImmutablePairStore(RubyArray receiver) { - return receiver.getArrayStore() instanceof ObjectImmutablePairArrayStore; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ArrayNodes.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ArrayNodes.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1080 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.core; - -import java.util.*; - -import com.oracle.truffle.api.CompilerDirectives.SlowPath; -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.utilities.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.control.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.core.array.*; -import com.oracle.truffle.ruby.runtime.core.range.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -@CoreClass(name = "Array") -public abstract class ArrayNodes { - - @CoreMethod(names = "+", minArgs = 1, maxArgs = 1) - public abstract static class AddNode extends CoreMethodNode { - - public AddNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public AddNode(AddNode prev) { - super(prev); - } - - @Specialization - public RubyArray equal(RubyArray a, RubyArray b) { - final RubyArray result = new RubyArray(getContext().getCoreLibrary().getArrayClass()); - result.setRangeArrayExclusive(0, 0, a); - result.setRangeArrayExclusive(a.size(), a.size(), b); - return result; - } - - } - - @CoreMethod(names = "-", minArgs = 1, maxArgs = 1) - public abstract static class SubNode extends CoreMethodNode { - - public SubNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public SubNode(SubNode prev) { - super(prev); - } - - @Specialization - public RubyArray equal(RubyArray a, RubyArray b) { - return a.relativeComplement(b); - } - - } - - @CoreMethod(names = "*", minArgs = 1, maxArgs = 1) - public abstract static class MulNode extends CoreMethodNode { - - public MulNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public MulNode(MulNode prev) { - super(prev); - } - - @Specialization - public RubyArray mul(RubyArray array, int count) { - // TODO(CS): use the same storage type - - final RubyArray result = new RubyArray(array.getRubyClass().getContext().getCoreLibrary().getArrayClass()); - - for (int n = 0; n < count; n++) { - for (int i = 0; i < array.size(); i++) { - result.push(array.get(i)); - } - } - - return result; - } - - } - - @CoreMethod(names = "==", minArgs = 1, maxArgs = 1) - public abstract static class EqualNode extends CoreMethodNode { - - public EqualNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public EqualNode(EqualNode prev) { - super(prev); - } - - @Specialization - public boolean equal(RubyArray a, RubyArray b) { - // TODO(CS) - return a.equals(b); - } - - } - - @CoreMethod(names = "[]", minArgs = 1, maxArgs = 2) - public abstract static class IndexNode extends ArrayCoreMethodNode { - - public IndexNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public IndexNode(IndexNode prev) { - super(prev); - } - - @Specialization(guards = "isEmptyStore", order = 1) - public NilPlaceholder indexEmpty(@SuppressWarnings("unused") RubyArray array, @SuppressWarnings("unused") int index, @SuppressWarnings("unused") UndefinedPlaceholder unused) { - return NilPlaceholder.INSTANCE; - } - - @Specialization(guards = "isFixnumStore", rewriteOn = UnexpectedResultException.class, order = 2) - public int indexFixnum(RubyArray array, int index, @SuppressWarnings("unused") UndefinedPlaceholder unused) throws UnexpectedResultException { - final FixnumArrayStore store = (FixnumArrayStore) array.getArrayStore(); - return store.getFixnum(ArrayUtilities.normaliseIndex(store.size(), index)); - } - - @Specialization(guards = "isFixnumStore", order = 3) - public Object indexMaybeFixnum(RubyArray array, int index, @SuppressWarnings("unused") UndefinedPlaceholder unused) { - final FixnumArrayStore store = (FixnumArrayStore) array.getArrayStore(); - - try { - return store.getFixnum(ArrayUtilities.normaliseIndex(store.size(), index)); - } catch (UnexpectedResultException e) { - return e.getResult(); - } - } - - @Specialization(guards = "isFixnumImmutablePairStore", rewriteOn = UnexpectedResultException.class, order = 4) - public int indexFixnumImmutablePair(RubyArray array, int index, @SuppressWarnings("unused") UndefinedPlaceholder unused) throws UnexpectedResultException { - final FixnumImmutablePairArrayStore store = (FixnumImmutablePairArrayStore) array.getArrayStore(); - return store.getFixnum(ArrayUtilities.normaliseIndex(store.size(), index)); - } - - @Specialization(guards = "isFixnumImmutablePairStore", order = 5) - public Object indexMaybeFixnumImmutablePair(RubyArray array, int index, @SuppressWarnings("unused") UndefinedPlaceholder unused) { - final FixnumImmutablePairArrayStore store = (FixnumImmutablePairArrayStore) array.getArrayStore(); - - try { - return store.getFixnum(ArrayUtilities.normaliseIndex(store.size(), index)); - } catch (UnexpectedResultException e) { - return e.getResult(); - } - } - - @Specialization(guards = "isObjectStore", order = 6) - public Object indexObject(RubyArray array, int index, @SuppressWarnings("unused") UndefinedPlaceholder unused) { - final ObjectArrayStore store = (ObjectArrayStore) array.getArrayStore(); - return store.get(ArrayUtilities.normaliseIndex(store.size(), index)); - } - - @Specialization(guards = "isObjectImmutablePairStore", order = 7) - public Object indexObjectImmutablePair(RubyArray array, int index, @SuppressWarnings("unused") UndefinedPlaceholder unused) { - final ObjectImmutablePairArrayStore store = (ObjectImmutablePairArrayStore) array.getArrayStore(); - return store.get(ArrayUtilities.normaliseIndex(store.size(), index)); - } - - @Specialization(order = 8) - public Object indexRange(RubyArray array, int begin, int rangeLength) { - final int length = array.size(); - final int normalisedBegin = ArrayUtilities.normaliseIndex(length, begin); - return array.getRangeExclusive(normalisedBegin, normalisedBegin + rangeLength); - } - - @Specialization(order = 9) - public Object indexRange(RubyArray array, FixnumRange range, @SuppressWarnings("unused") UndefinedPlaceholder unused) { - if (range.doesExcludeEnd()) { - return array.getRangeExclusive(range.getBegin(), range.getExclusiveEnd()); - } else { - return array.getRangeInclusive(range.getBegin(), range.getInclusiveEnd()); - } - } - - } - - @CoreMethod(names = "[]=", minArgs = 2, maxArgs = 3) - public abstract static class IndexSetNode extends ArrayCoreMethodNode { - - public IndexSetNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public IndexSetNode(IndexSetNode prev) { - super(prev); - } - - @Specialization(guards = "isEmptyStore", order = 1) - public Object indexSetEmpty(RubyArray array, int index, Object value, @SuppressWarnings("unused") UndefinedPlaceholder unused) { - array.set(index, value); - return value; - } - - @Specialization(guards = "isFixnumStore", rewriteOn = GeneraliseArrayStoreException.class, order = 2) - public int indexSetFixnum(RubyArray array, int index, int value, @SuppressWarnings("unused") UndefinedPlaceholder unused) throws GeneraliseArrayStoreException { - final FixnumArrayStore store = (FixnumArrayStore) array.getArrayStore(); - final int normalisedIndex = ArrayUtilities.normaliseIndex(store.size(), index); - store.setFixnum(normalisedIndex, value); - return value; - } - - @Specialization(guards = "isFixnumStore", order = 3) - public int indexSetFixnumMayGeneralise(RubyArray array, int index, int value, @SuppressWarnings("unused") UndefinedPlaceholder unused) { - final FixnumArrayStore store = (FixnumArrayStore) array.getArrayStore(); - final int normalisedIndex = ArrayUtilities.normaliseIndex(store.size(), index); - - try { - store.setFixnum(normalisedIndex, value); - } catch (GeneraliseArrayStoreException e) { - array.set(normalisedIndex, value); - } - - return value; - } - - @Specialization(guards = "isObjectStore", order = 4) - public Object indexSetObject(RubyArray array, int index, Object value, @SuppressWarnings("unused") UndefinedPlaceholder unused) { - final ObjectArrayStore store = (ObjectArrayStore) array.getArrayStore(); - final int normalisedIndex = ArrayUtilities.normaliseIndex(store.size(), index); - - try { - store.set(normalisedIndex, value); - } catch (GeneraliseArrayStoreException e) { - array.set(normalisedIndex, value); - } - - return value; - } - - @Specialization(order = 5) - public RubyArray indexSetRange(RubyArray array, FixnumRange range, RubyArray value, @SuppressWarnings("unused") UndefinedPlaceholder unused) { - if (range.doesExcludeEnd()) { - array.setRangeArrayExclusive(range.getBegin(), range.getExclusiveEnd(), value); - } else { - array.setRangeArrayInclusive(range.getBegin(), range.getInclusiveEnd(), value); - } - - return value; - } - - @Specialization(order = 6) - public Object indexSetRange(RubyArray array, FixnumRange range, Object value, @SuppressWarnings("unused") UndefinedPlaceholder unused) { - if (range.doesExcludeEnd()) { - array.setRangeSingleExclusive(range.getBegin(), range.getExclusiveEnd(), value); - } else { - array.setRangeSingleInclusive(range.getBegin(), range.getInclusiveEnd(), value); - } - - return value; - } - - @Specialization(order = 7) - public RubyArray indexSetRange(RubyArray array, int begin, int rangeLength, RubyArray value) { - array.setRangeArrayExclusive(begin, begin + rangeLength, value); - return value; - } - - @Specialization(order = 8) - public Object indexSetRange(RubyArray array, int begin, int rangeLength, Object value) { - if (value instanceof UndefinedPlaceholder) { - if (array.getArrayStore() instanceof EmptyArrayStore) { - return indexSetEmpty(array, begin, rangeLength, UndefinedPlaceholder.INSTANCE); - } else if (array.getArrayStore() instanceof FixnumArrayStore) { - return indexSetFixnumMayGeneralise(array, begin, rangeLength, UndefinedPlaceholder.INSTANCE); - } else { - return indexSetObject(array, begin, rangeLength, UndefinedPlaceholder.INSTANCE); - } - } - - array.setRangeSingleExclusive(begin, begin + rangeLength, value); - return value; - } - - } - - @CoreMethod(names = "all?", needsBlock = true, maxArgs = 0) - public abstract static class AllNode extends YieldingCoreMethodNode { - - public AllNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public AllNode(AllNode prev) { - super(prev); - } - - @Specialization - public boolean all(VirtualFrame frame, RubyArray array, RubyProc block) { - for (Object value : array.asList()) { - if (!yieldBoolean(frame, block, value)) { - return false; - } - } - - return true; - } - - } - - @CoreMethod(names = "any?", needsBlock = true, maxArgs = 0) - public abstract static class AnyNode extends YieldingCoreMethodNode { - - public AnyNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public AnyNode(AnyNode prev) { - super(prev); - } - - @Specialization - public boolean any(VirtualFrame frame, RubyArray array, RubyProc block) { - for (Object value : array.asList()) { - if (yieldBoolean(frame, block, value)) { - return true; - } - } - - return false; - } - - } - - @CoreMethod(names = "compact", maxArgs = 0) - public abstract static class CompactNode extends ArrayCoreMethodNode { - - public CompactNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public CompactNode(CompactNode prev) { - super(prev); - } - - @Specialization - public RubyArray compat(RubyArray array) { - final RubyArray result = new RubyArray(array.getRubyClass().getContext().getCoreLibrary().getArrayClass()); - - for (Object value : array.asList()) { - if (!(value instanceof NilPlaceholder || value instanceof RubyNilClass)) { - result.push(value); - } - } - - return result; - } - - } - - @CoreMethod(names = "concat", minArgs = 1, maxArgs = 1) - public abstract static class ConcatNode extends CoreMethodNode { - - public ConcatNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ConcatNode(ConcatNode prev) { - super(prev); - } - - @Specialization - public RubyArray concat(RubyArray array, RubyArray other) { - array.setRangeArrayExclusive(array.size(), array.size(), other); - return array; - } - - } - - @CoreMethod(names = "delete", minArgs = 1, maxArgs = 1) - public abstract static class DeleteNode extends CoreMethodNode { - - public DeleteNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public DeleteNode(DeleteNode prev) { - super(prev); - } - - @Specialization - public Object delete(RubyArray array, Object value) { - boolean deleted = false; - int n = 0; - - while (n < array.size()) { - if (array.get(n) == value) { - array.deleteAt(n); - deleted = true; - } else { - n++; - } - } - - if (deleted) { - return value; - } else { - return NilPlaceholder.INSTANCE; - } - } - - } - - @CoreMethod(names = "delete_at", minArgs = 1, maxArgs = 1) - public abstract static class DeleteAtNode extends CoreMethodNode { - - public DeleteAtNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public DeleteAtNode(DeleteAtNode prev) { - super(prev); - } - - @Specialization - public Object deleteAt(RubyArray array, int index) { - return array.deleteAt(index); - } - - } - - @CoreMethod(names = "dup", maxArgs = 0) - public abstract static class DupNode extends ArrayCoreMethodNode { - - public DupNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public DupNode(DupNode prev) { - super(prev); - } - - @Specialization - public Object dup(RubyArray array) { - return array.dup(); - } - - } - - @CoreMethod(names = "each", needsBlock = true, maxArgs = 0) - public abstract static class EachNode extends YieldingCoreMethodNode { - - private final BranchProfile breakProfile = new BranchProfile(); - private final BranchProfile nextProfile = new BranchProfile(); - private final BranchProfile redoProfile = new BranchProfile(); - - public EachNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public EachNode(EachNode prev) { - super(prev); - } - - @Specialization - public Object each(VirtualFrame frame, RubyArray array, RubyProc block) { - outer: for (int n = 0; n < array.size(); n++) { - while (true) { - try { - yield(frame, block, array.get(n)); - continue outer; - } catch (BreakException e) { - breakProfile.enter(); - return e.getResult(); - } catch (NextException e) { - nextProfile.enter(); - continue outer; - } catch (RedoException e) { - redoProfile.enter(); - } - } - } - - return NilPlaceholder.INSTANCE; - } - - } - - @CoreMethod(names = "each_with_index", needsBlock = true, maxArgs = 0) - public abstract static class EachWithIndexNode extends YieldingCoreMethodNode { - - public EachWithIndexNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public EachWithIndexNode(EachWithIndexNode prev) { - super(prev); - } - - @Specialization - public NilPlaceholder eachWithIndex(VirtualFrame frame, RubyArray array, RubyProc block) { - for (int n = 0; n < array.size(); n++) { - try { - yield(frame, block, array.get(n), n); - } catch (BreakException e) { - break; - } - } - - return NilPlaceholder.INSTANCE; - } - - } - - @CoreMethod(names = "empty?", maxArgs = 0) - public abstract static class EmptyNode extends ArrayCoreMethodNode { - - public EmptyNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public EmptyNode(EmptyNode prev) { - super(prev); - } - - @Specialization - public boolean isEmpty(RubyArray array) { - return array.isEmpty(); - } - - } - - @CoreMethod(names = "find", needsBlock = true, maxArgs = 0) - public abstract static class FindNode extends YieldingCoreMethodNode { - - public FindNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public FindNode(FindNode prev) { - super(prev); - } - - @Specialization - public Object find(VirtualFrame frame, RubyArray array, RubyProc block) { - for (int n = 0; n < array.size(); n++) { - try { - final Object value = array.get(n); - - if (yieldBoolean(frame, block, value)) { - return value; - } - } catch (BreakException e) { - break; - } - } - - return NilPlaceholder.INSTANCE; - } - } - - @CoreMethod(names = "first", maxArgs = 0) - public abstract static class FirstNode extends ArrayCoreMethodNode { - - public FirstNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public FirstNode(FirstNode prev) { - super(prev); - } - - @Specialization - public Object first(RubyArray array) { - if (array.size() == 0) { - return NilPlaceholder.INSTANCE; - } else { - return array.get(0); - } - } - - } - - @CoreMethod(names = "flatten", maxArgs = 0) - public abstract static class FlattenNode extends ArrayCoreMethodNode { - - public FlattenNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public FlattenNode(FlattenNode prev) { - super(prev); - } - - @Specialization - public RubyArray flatten(RubyArray array) { - final RubyArray result = new RubyArray(array.getRubyClass().getContext().getCoreLibrary().getArrayClass()); - array.flattenTo(result); - return result; - } - - } - - @CoreMethod(names = "include?", minArgs = 1, maxArgs = 1) - public abstract static class IncludeNode extends ArrayCoreMethodNode { - - public IncludeNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public IncludeNode(IncludeNode prev) { - super(prev); - } - - @Specialization - public boolean include(RubyArray array, Object value) { - return array.contains(value); - } - - } - - @CoreMethod(names = {"inject", "reduce"}, needsBlock = true, minArgs = 0, maxArgs = 1) - public abstract static class InjectNode extends YieldingCoreMethodNode { - - public InjectNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public InjectNode(InjectNode prev) { - super(prev); - } - - @Specialization - public Object inject(VirtualFrame frame, RubyArray array, @SuppressWarnings("unused") UndefinedPlaceholder initial, RubyProc block) { - Object accumulator = array.get(0); - - for (int n = 1; n < array.size(); n++) { - accumulator = yield(frame, block, accumulator, array.get(n)); - } - - return accumulator; - } - - @Specialization - public Object inject(VirtualFrame frame, RubyArray array, Object initial, RubyProc block) { - if (initial instanceof UndefinedPlaceholder) { - return inject(frame, array, UndefinedPlaceholder.INSTANCE, block); - } - - Object accumulator = initial; - - for (int n = 0; n < array.size(); n++) { - accumulator = yield(frame, block, accumulator, array.get(n)); - } - - return accumulator; - } - - } - - @CoreMethod(names = "insert", minArgs = 2, maxArgs = 2) - public abstract static class InsertNode extends ArrayCoreMethodNode { - - public InsertNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public InsertNode(InsertNode prev) { - super(prev); - } - - @Specialization(guards = "isFixnumStore", rewriteOn = GeneraliseArrayStoreException.class) - public int insert(RubyArray array, int index, int value) throws GeneraliseArrayStoreException { - final FixnumArrayStore store = (FixnumArrayStore) array.getArrayStore(); - store.insertFixnum(ArrayUtilities.normaliseIndex(store.size(), index), value); - return value; - } - - @Specialization - public Object insert(RubyArray array, int index, Object value) { - array.insert(ArrayUtilities.normaliseIndex(array.size(), index), value); - return value; - } - - } - - @CoreMethod(names = {"inspect", "to_s"}, maxArgs = 0) - public abstract static class InspectNode extends CoreMethodNode { - - public InspectNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public InspectNode(InspectNode prev) { - super(prev); - } - - @Specialization - public RubyString inspect(RubyArray array) { - final RubyContext context = getContext(); - return getContext().makeString(inspect(context, array)); - } - - @SlowPath - private static String inspect(RubyContext context, RubyArray array) { - final StringBuilder builder = new StringBuilder(); - - builder.append("["); - - for (int n = 0; n < array.size(); n++) { - if (n > 0) { - builder.append(", "); - } - - // TODO(CS): slow path send - builder.append(context.getCoreLibrary().box(array.get(n)).send("inspect", null)); - } - - builder.append("]"); - - return builder.toString(); - } - - } - - @CoreMethod(names = "join", minArgs = 1, maxArgs = 1) - public abstract static class JoinNode extends ArrayCoreMethodNode { - - public JoinNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public JoinNode(JoinNode prev) { - super(prev); - } - - @Specialization - public RubyString join(RubyArray array, RubyString separator) { - return array.getRubyClass().getContext().makeString(array.join(separator.toString())); - } - - } - - @CoreMethod(names = "last", maxArgs = 0) - public abstract static class LastNode extends ArrayCoreMethodNode { - - public LastNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public LastNode(LastNode prev) { - super(prev); - } - - @Specialization - public Object last(RubyArray array) { - final int size = array.size(); - if (size == 0) { - return NilPlaceholder.INSTANCE; - } else { - return array.get(size - 1); - } - } - - } - - @CoreMethod(names = {"map", "collect"}, needsBlock = true, maxArgs = 0) - public abstract static class MapNode extends YieldingCoreMethodNode { - - public MapNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public MapNode(MapNode prev) { - super(prev); - } - - @Specialization - public RubyArray map(VirtualFrame frame, RubyArray array, RubyProc block) { - final RubyArray result = new RubyArray(array.getRubyClass().getContext().getCoreLibrary().getArrayClass()); - - for (int n = 0; n < array.size(); n++) { - result.push(yield(frame, block, array.get(n))); - } - - return result; - } - } - - @CoreMethod(names = {"map!", "collect!"}, needsBlock = true, maxArgs = 0) - public abstract static class MapInPlaceNode extends YieldingCoreMethodNode { - - public MapInPlaceNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public MapInPlaceNode(MapInPlaceNode prev) { - super(prev); - } - - @Specialization - public RubyArray mapInPlace(VirtualFrame frame, RubyArray array, RubyProc block) { - for (int n = 0; n < array.size(); n++) { - array.set(n, yield(frame, block, array.get(n))); - } - - return array; - } - } - - @CoreMethod(names = "pop", maxArgs = 0) - public abstract static class PopNode extends ArrayCoreMethodNode { - - public PopNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public PopNode(PopNode prev) { - super(prev); - } - - @Specialization - public Object pop(RubyArray array) { - final int size = array.size(); - - if (size == 0) { - return NilPlaceholder.INSTANCE; - } else { - return array.deleteAt(size - 1); - } - } - - } - - @CoreMethod(names = "product", isSplatted = true) - public abstract static class ProductNode extends ArrayCoreMethodNode { - - public ProductNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ProductNode(ProductNode prev) { - super(prev); - } - - @Specialization - public Object product(RubyArray array, Object... args) { - final RubyArray[] arrays = new RubyArray[1 + args.length]; - arrays[0] = array; - System.arraycopy(args, 0, arrays, 1, args.length); - return RubyArray.product(array.getRubyClass().getContext().getCoreLibrary().getArrayClass(), arrays, arrays.length); - } - - } - - @CoreMethod(names = {"push", "<<"}, isSplatted = true) - public abstract static class PushNode extends CoreMethodNode { - - public PushNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public PushNode(PushNode prev) { - super(prev); - } - - @Specialization - public RubyArray push(RubyArray array, Object... args) { - for (int n = 0; n < args.length; n++) { - array.push(args[n]); - } - - return array; - } - - } - - @CoreMethod(names = "reject!", needsBlock = true, maxArgs = 0) - public abstract static class RejectInPlaceNode extends YieldingCoreMethodNode { - - public RejectInPlaceNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public RejectInPlaceNode(RejectInPlaceNode prev) { - super(prev); - } - - @Specialization - public Object rejectInPlace(VirtualFrame frame, RubyArray array, RubyProc block) { - boolean modified = false; - int n = 0; - - while (n < array.size()) { - if (yieldBoolean(frame, block, array.get(n))) { - array.deleteAt(n); - modified = true; - } else { - n++; - } - } - - if (modified) { - return array; - } else { - return NilPlaceholder.INSTANCE; - } - } - - } - - @CoreMethod(names = "select", needsBlock = true, maxArgs = 0) - public abstract static class SelectNode extends YieldingCoreMethodNode { - - public SelectNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public SelectNode(SelectNode prev) { - super(prev); - } - - @Specialization - public Object select(VirtualFrame frame, RubyArray array, RubyProc block) { - final RubyArray result = new RubyArray(getContext().getCoreLibrary().getArrayClass()); - - for (int n = 0; n < array.size(); n++) { - final Object value = array.get(n); - - if (yieldBoolean(frame, block, value)) { - result.push(value); - } - } - - return result; - } - - } - - @CoreMethod(names = "shift", maxArgs = 0) - public abstract static class ShiftNode extends CoreMethodNode { - - public ShiftNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ShiftNode(ShiftNode prev) { - super(prev); - } - - @Specialization - public Object shift(RubyArray array) { - final int size = array.size(); - - if (size == 0) { - return NilPlaceholder.INSTANCE; - } else { - return array.deleteAt(0); - } - } - - } - - @CoreMethod(names = {"size", "length"}, maxArgs = 0) - public abstract static class SizeNode extends ArrayCoreMethodNode { - - public SizeNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public SizeNode(SizeNode prev) { - super(prev); - } - - @Specialization - public int size(RubyArray array) { - return array.size(); - } - - } - - @CoreMethod(names = "sort", maxArgs = 0) - public abstract static class SortNode extends CoreMethodNode { - - public SortNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public SortNode(SortNode prev) { - super(prev); - } - - @Specialization - public RubyArray sort(RubyArray array) { - final RubyContext context = array.getRubyClass().getContext(); - - final Object[] objects = array.asList().toArray(); - - Arrays.sort(objects, new Comparator() { - - @Override - public int compare(Object a, Object b) { - final RubyBasicObject aBoxed = context.getCoreLibrary().box(a); - return (int) aBoxed.getLookupNode().lookupMethod("<=>").call(null, aBoxed, null, b); - } - - }); - - return RubyArray.specializedFromObjects(context.getCoreLibrary().getArrayClass(), objects); - } - - } - - @CoreMethod(names = "unshift", isSplatted = true) - public abstract static class UnshiftNode extends CoreMethodNode { - - public UnshiftNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public UnshiftNode(UnshiftNode prev) { - super(prev); - } - - @Specialization - public Object unshift(RubyArray array, Object... args) { - for (int n = 0; n < args.length; n++) { - array.unshift(args[n]); - } - - return array; - } - - } - - @CoreMethod(names = "zip", isSplatted = true) - public abstract static class ZipNode extends CoreMethodNode { - - public ZipNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ZipNode(ZipNode prev) { - super(prev); - } - - @Specialization - public RubyArray zip(RubyArray array, Object... args) { - final RubyContext context = getContext(); - final RubyClass arrayClass = context.getCoreLibrary().getArrayClass(); - - final RubyArray result = new RubyArray(arrayClass); - - for (int n = 0; n < array.size(); n++) { - final RubyArray tuple = new RubyArray(arrayClass); - - tuple.push(array.get(n)); - - for (Object arg : args) { - final RubyArray argArray = (RubyArray) arg; - tuple.push(argArray.get(n)); - } - - result.push(tuple); - } - - return result; - } - - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ArrayPushNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ArrayPushNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.core; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.array.*; - -public class ArrayPushNode extends RubyNode { - - @Child protected RubyNode array; - @Child protected RubyNode pushed; - - public ArrayPushNode(RubyContext context, SourceSection sourceSection, RubyNode array, RubyNode pushed) { - super(context, sourceSection); - this.array = adoptChild(array); - this.pushed = adoptChild(pushed); - } - - @Override - public Object execute(VirtualFrame frame) { - RubyArray a = (RubyArray) array.execute(frame); - a = (RubyArray) a.dup(); - a.push(pushed.execute(frame)); - return a; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ArrayRestNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ArrayRestNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.core; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.array.*; - -/** - * Take the rest of values in an array after an index, without using any method lookup. This isn't a - * call - it's an operation on a core class. - */ -@NodeInfo(shortName = "array-rest") -public final class ArrayRestNode extends RubyNode { - - final int begin; - @Child protected RubyNode array; - - public ArrayRestNode(RubyContext context, SourceSection sourceSection, int begin, RubyNode array) { - super(context, sourceSection); - this.begin = begin; - this.array = adoptChild(array); - } - - @Override - public Object execute(VirtualFrame frame) { - final RubyArray arrayObject = (RubyArray) array.execute(frame); - return arrayObject.getRangeExclusive(begin, arrayObject.size()); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/BasicObjectNodes.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/BasicObjectNodes.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,162 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.core; - -import java.math.*; -import java.util.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -@CoreClass(name = "BasicObject") -public abstract class BasicObjectNodes { - - @CoreMethod(names = "!", needsSelf = false, maxArgs = 0) - public abstract static class NotNode extends CoreMethodNode { - - public NotNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public NotNode(NotNode prev) { - super(prev); - } - - @Specialization - public boolean not() { - return false; - } - - } - - @CoreMethod(names = "==", minArgs = 1, maxArgs = 1) - public abstract static class EqualNode extends CoreMethodNode { - - public EqualNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public EqualNode(EqualNode prev) { - super(prev); - } - - @Specialization - public boolean equal(Object a, Object b) { - // TODO(CS) ideally all classes would do this in their own nodes - return a.equals(b); - } - - } - - @CoreMethod(names = "!=", minArgs = 1, maxArgs = 1) - public abstract static class NotEqualNode extends CoreMethodNode { - - public NotEqualNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public NotEqualNode(NotEqualNode prev) { - super(prev); - } - - @Specialization - public boolean notEqual(Object a, Object b) { - // TODO(CS) ideally all classes would do this in their own nodes - return !a.equals(b); - } - - } - - @CoreMethod(names = "equal?", minArgs = 1, maxArgs = 1) - public abstract static class ReferenceEqualNode extends CoreMethodNode { - - public ReferenceEqualNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ReferenceEqualNode(ReferenceEqualNode prev) { - super(prev); - } - - @Specialization(order = 1) - public boolean equal(@SuppressWarnings("unused") NilPlaceholder a, @SuppressWarnings("unused") NilPlaceholder b) { - return true; - } - - @Specialization(order = 2) - public boolean equal(int a, int b) { - return a == b; - } - - @Specialization(order = 3) - public boolean equal(double a, double b) { - return a == b; - } - - @Specialization(order = 4) - public boolean equal(BigInteger a, BigInteger b) { - return a.compareTo(b) == 0; - } - - @Specialization(order = 5) - public boolean equal(RubyBasicObject a, RubyBasicObject b) { - return a == b; - } - } - - @CoreMethod(names = "initialize", needsSelf = false, maxArgs = 0) - public abstract static class InitializeNode extends CoreMethodNode { - - public InitializeNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public InitializeNode(InitializeNode prev) { - super(prev); - } - - @Specialization - public NilPlaceholder initiailze() { - return NilPlaceholder.INSTANCE; - } - - } - - @CoreMethod(names = {"send", "__send__"}, needsSelf = true, needsBlock = true, minArgs = 1, isSplatted = true) - public abstract static class SendNode extends CoreMethodNode { - - public SendNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public SendNode(SendNode prev) { - super(prev); - } - - @Specialization - public Object send(RubyBasicObject self, Object[] args, @SuppressWarnings("unused") UndefinedPlaceholder block) { - final String name = args[0].toString(); - final Object[] sendArgs = Arrays.copyOfRange(args, 1, args.length); - return self.send(name, null, sendArgs); - } - - @Specialization - public Object send(RubyBasicObject self, Object[] args, RubyProc block) { - final String name = args[0].toString(); - final Object[] sendArgs = Arrays.copyOfRange(args, 1, args.length); - return self.send(name, block, sendArgs); - } - - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/BignumNodes.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/BignumNodes.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,661 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.core; - -import java.math.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.utilities.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.control.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.core.array.*; - -@CoreClass(name = "Bignum") -public abstract class BignumNodes { - - @CoreMethod(names = "+@", maxArgs = 0) - public abstract static class PosNode extends CoreMethodNode { - - public PosNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public PosNode(PosNode prev) { - super(prev); - } - - @Specialization - public BigInteger pos(BigInteger value) { - return value; - } - - } - - @CoreMethod(names = "-@", maxArgs = 0) - public abstract static class NegNode extends CoreMethodNode { - - public NegNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public NegNode(NegNode prev) { - super(prev); - } - - @Specialization - public BigInteger neg(BigInteger value) { - return value.negate(); - } - - } - - @CoreMethod(names = "+", minArgs = 1, maxArgs = 1) - public abstract static class AddNode extends CoreMethodNode { - - public AddNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public AddNode(AddNode prev) { - super(prev); - } - - @Specialization - public Object add(BigInteger a, int b) { - return a.add(BigInteger.valueOf(b)); - } - - @Specialization - public double add(BigInteger a, double b) { - return a.doubleValue() + b; - } - - @Specialization - public Object add(BigInteger a, BigInteger b) { - return GeneralConversions.fixnumOrBignum(a.add(b)); - } - - } - - @CoreMethod(names = "-", minArgs = 1, maxArgs = 1) - public abstract static class SubNode extends CoreMethodNode { - - public SubNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public SubNode(SubNode prev) { - super(prev); - } - - @Specialization - public Object sub(BigInteger a, int b) { - return a.subtract(BigInteger.valueOf(b)); - } - - @Specialization - public double sub(BigInteger a, double b) { - return a.doubleValue() - b; - } - - @Specialization - public Object sub(BigInteger a, BigInteger b) { - return GeneralConversions.fixnumOrBignum(a.subtract(b)); - } - - } - - @CoreMethod(names = "*", minArgs = 1, maxArgs = 1) - public abstract static class MulNode extends CoreMethodNode { - - public MulNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public MulNode(MulNode prev) { - super(prev); - } - - @Specialization - public Object mul(BigInteger a, int b) { - return a.multiply(BigInteger.valueOf(b)); - } - - @Specialization - public double mul(BigInteger a, double b) { - return a.doubleValue() * b; - } - - @Specialization - public Object mul(BigInteger a, BigInteger b) { - return GeneralConversions.fixnumOrBignum(a.multiply(b)); - } - - } - - @CoreMethod(names = "**", minArgs = 1, maxArgs = 1) - public abstract static class PowNode extends CoreMethodNode { - - public PowNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public PowNode(PowNode prev) { - super(prev); - } - - @Specialization - public BigInteger pow(BigInteger a, int b) { - return a.pow(b); - } - - @Specialization - public double pow(BigInteger a, double b) { - return Math.pow(a.doubleValue(), b); - } - - @Specialization - public BigInteger pow(BigInteger a, BigInteger b) { - BigInteger result = BigInteger.ONE; - - for (BigInteger n = BigInteger.ZERO; b.compareTo(b) < 0; n = n.add(BigInteger.ONE)) { - result = result.multiply(a); - } - - return result; - } - - } - - @CoreMethod(names = "/", minArgs = 1, maxArgs = 1) - public abstract static class DivNode extends CoreMethodNode { - - public DivNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public DivNode(DivNode prev) { - super(prev); - } - - @Specialization - public Object div(BigInteger a, int b) { - return a.divide(BigInteger.valueOf(b)); - } - - @Specialization - public double div(BigInteger a, double b) { - return a.doubleValue() / b; - } - - @Specialization - public Object div(BigInteger a, BigInteger b) { - return GeneralConversions.fixnumOrBignum(a.divide(b)); - } - - } - - @CoreMethod(names = "%", minArgs = 1, maxArgs = 1) - public abstract static class ModNode extends CoreMethodNode { - - public ModNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ModNode(ModNode prev) { - super(prev); - } - - @Specialization - public Object mod(BigInteger a, int b) { - return GeneralConversions.fixnumOrBignum(a.mod(BigInteger.valueOf(b))); - } - - @Specialization - public Object mod(@SuppressWarnings("unused") BigInteger a, @SuppressWarnings("unused") double b) { - throw new UnsupportedOperationException(); - } - - @Specialization - public Object mod(BigInteger a, BigInteger b) { - return GeneralConversions.fixnumOrBignum(a.mod(b)); - } - - } - - @CoreMethod(names = "divmod", minArgs = 1, maxArgs = 1) - public abstract static class DivModNode extends CoreMethodNode { - - public DivModNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public DivModNode(DivModNode prev) { - super(prev); - } - - @SuppressWarnings("unused") - @Specialization - public RubyArray divMod(VirtualFrame frame, BigInteger a, int b) { - return RubyBignum.divMod(getContext(), a, BigInteger.valueOf(b)); - } - - @Specialization - public RubyArray divMod(@SuppressWarnings("unused") BigInteger a, @SuppressWarnings("unused") double b) { - throw new UnsupportedOperationException(); - } - - @Specialization - public RubyArray divMod(BigInteger a, BigInteger b) { - return RubyBignum.divMod(getContext(), a, b); - } - - } - - @CoreMethod(names = "<", minArgs = 1, maxArgs = 1) - public abstract static class LessNode extends CoreMethodNode { - - public LessNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public LessNode(LessNode prev) { - super(prev); - } - - @Specialization - public boolean less(BigInteger a, int b) { - return a.compareTo(BigInteger.valueOf(b)) < 0; - } - - @Specialization - public boolean less(BigInteger a, double b) { - return a.compareTo(BigInteger.valueOf((long) b)) < 0; - } - - @Specialization - public boolean less(BigInteger a, BigInteger b) { - return a.compareTo(b) < 0; - } - } - - @CoreMethod(names = "<=", minArgs = 1, maxArgs = 1) - public abstract static class LessEqualNode extends CoreMethodNode { - - public LessEqualNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public LessEqualNode(LessEqualNode prev) { - super(prev); - } - - @Specialization - public boolean lessEqual(BigInteger a, int b) { - return a.compareTo(BigInteger.valueOf(b)) <= 0; - } - - @Specialization - public boolean lessEqual(BigInteger a, double b) { - return a.compareTo(BigInteger.valueOf((long) b)) <= 0; - } - - @Specialization - public boolean lessEqual(BigInteger a, BigInteger b) { - return a.compareTo(b) <= 0; - } - } - - @CoreMethod(names = "==", minArgs = 1, maxArgs = 1) - public abstract static class EqualNode extends CoreMethodNode { - - public EqualNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public EqualNode(EqualNode prev) { - super(prev); - } - - @Specialization - public boolean equal(BigInteger a, int b) { - return a.compareTo(BigInteger.valueOf(b)) == 0; - } - - @Specialization - public boolean equal(BigInteger a, double b) { - return a.compareTo(BigInteger.valueOf((long) b)) == 0; - } - - @Specialization - public boolean equal(BigInteger a, BigInteger b) { - return a.compareTo(b) == 0; - } - } - - @CoreMethod(names = "<=>", minArgs = 1, maxArgs = 1) - public abstract static class CompareNode extends CoreMethodNode { - - public CompareNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public CompareNode(CompareNode prev) { - super(prev); - } - - @Specialization - public int compare(BigInteger a, int b) { - return a.compareTo(BigInteger.valueOf(b)); - } - - @Specialization - public int compare(BigInteger a, double b) { - return a.compareTo(BigInteger.valueOf((long) b)); - } - - @Specialization - public int compare(BigInteger a, BigInteger b) { - return a.compareTo(b); - } - } - - @CoreMethod(names = "!=", minArgs = 1, maxArgs = 1) - public abstract static class NotEqualNode extends CoreMethodNode { - - public NotEqualNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public NotEqualNode(NotEqualNode prev) { - super(prev); - } - - @Specialization - public boolean notEqual(BigInteger a, int b) { - return a.compareTo(BigInteger.valueOf(b)) != 0; - } - - @Specialization - public boolean notEqual(BigInteger a, double b) { - return a.compareTo(BigInteger.valueOf((long) b)) != 0; - } - - @Specialization - public boolean notEqual(BigInteger a, BigInteger b) { - return a.compareTo(b) != 0; - } - } - - @CoreMethod(names = ">=", minArgs = 1, maxArgs = 1) - public abstract static class GreaterEqualNode extends CoreMethodNode { - - public GreaterEqualNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public GreaterEqualNode(GreaterEqualNode prev) { - super(prev); - } - - @Specialization - public boolean greaterEqual(BigInteger a, int b) { - return a.compareTo(BigInteger.valueOf(b)) >= 0; - } - - @Specialization - public boolean greaterEqual(BigInteger a, double b) { - return a.compareTo(BigInteger.valueOf((long) b)) >= 0; - } - - @Specialization - public boolean greaterEqual(BigInteger a, BigInteger b) { - return a.compareTo(b) >= 0; - } - } - - @CoreMethod(names = ">", minArgs = 1, maxArgs = 1) - public abstract static class GreaterNode extends CoreMethodNode { - - public GreaterNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public GreaterNode(GreaterNode prev) { - super(prev); - } - - @Specialization - public boolean equal(BigInteger a, int b) { - return a.compareTo(BigInteger.valueOf(b)) > 0; - } - - @Specialization - public boolean equal(BigInteger a, double b) { - return a.compareTo(BigInteger.valueOf((long) b)) > 0; - } - - @Specialization - public boolean equal(BigInteger a, BigInteger b) { - return a.compareTo(b) > 0; - } - } - - @CoreMethod(names = "&", minArgs = 1, maxArgs = 1) - public abstract static class BitAndNode extends CoreMethodNode { - - public BitAndNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public BitAndNode(BitAndNode prev) { - super(prev); - } - - @Specialization - public Object bitAnd(BigInteger a, int b) { - return GeneralConversions.fixnumOrBignum(a.and(BigInteger.valueOf(b))); - } - - @Specialization - public Object bitAnd(BigInteger a, BigInteger b) { - return GeneralConversions.fixnumOrBignum(a.and(b)); - } - } - - @CoreMethod(names = "|", minArgs = 1, maxArgs = 1) - public abstract static class BitOrNode extends CoreMethodNode { - - public BitOrNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public BitOrNode(BitOrNode prev) { - super(prev); - } - - @Specialization - public Object bitOr(BigInteger a, int b) { - return GeneralConversions.fixnumOrBignum(a.or(BigInteger.valueOf(b))); - } - - @Specialization - public Object bitOr(BigInteger a, BigInteger b) { - return GeneralConversions.fixnumOrBignum(a.or(b)); - } - } - - @CoreMethod(names = "^", minArgs = 1, maxArgs = 1) - public abstract static class BitXOrNode extends CoreMethodNode { - - public BitXOrNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public BitXOrNode(BitXOrNode prev) { - super(prev); - } - - @Specialization - public Object bitXOr(BigInteger a, int b) { - return GeneralConversions.fixnumOrBignum(a.xor(BigInteger.valueOf(b))); - } - - @Specialization - public Object bitXOr(BigInteger a, BigInteger b) { - return GeneralConversions.fixnumOrBignum(a.xor(b)); - } - } - - @CoreMethod(names = "<<", minArgs = 1, maxArgs = 1) - public abstract static class LeftShiftNode extends CoreMethodNode { - - public LeftShiftNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public LeftShiftNode(LeftShiftNode prev) { - super(prev); - } - - @Specialization - public Object leftShift(BigInteger a, int b) { - if (b >= 0) { - return GeneralConversions.fixnumOrBignum(a.shiftLeft(b)); - } else { - return GeneralConversions.fixnumOrBignum(a.shiftRight(-b)); - } - } - - } - - @CoreMethod(names = ">>", minArgs = 1, maxArgs = 1) - public abstract static class RightShiftNode extends CoreMethodNode { - - public RightShiftNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public RightShiftNode(RightShiftNode prev) { - super(prev); - } - - @Specialization - public Object leftShift(BigInteger a, int b) { - if (b >= 0) { - return GeneralConversions.fixnumOrBignum(a.shiftRight(b)); - } else { - return GeneralConversions.fixnumOrBignum(a.shiftLeft(-b)); - } - } - - } - - @CoreMethod(names = "inspect", maxArgs = 0) - public abstract static class InpsectNode extends CoreMethodNode { - - public InpsectNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public InpsectNode(InpsectNode prev) { - super(prev); - } - - @Specialization - public RubyString inspect(BigInteger n) { - return getContext().makeString(n.toString()); - } - - } - - @CoreMethod(names = "nonzero?", maxArgs = 0) - public abstract static class NonZeroNode extends CoreMethodNode { - - public NonZeroNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public NonZeroNode(NonZeroNode prev) { - super(prev); - } - - @Specialization - public Object nonZero(BigInteger value) { - if (value.compareTo(BigInteger.ZERO) == 0) { - return false; - } else { - return value; - } - } - - } - - @CoreMethod(names = "times", needsBlock = true, maxArgs = 0) - public abstract static class TimesNode extends YieldingCoreMethodNode { - - private final BranchProfile breakProfile = new BranchProfile(); - private final BranchProfile nextProfile = new BranchProfile(); - private final BranchProfile redoProfile = new BranchProfile(); - - public TimesNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public TimesNode(TimesNode prev) { - super(prev); - } - - @Specialization - public Object times(VirtualFrame frame, BigInteger n, RubyProc block) { - outer: for (BigInteger i = BigInteger.ZERO; i.compareTo(n) < 0; i = i.add(BigInteger.ONE)) { - while (true) { - try { - yield(frame, block, i); - continue outer; - } catch (BreakException e) { - breakProfile.enter(); - return e.getResult(); - } catch (NextException e) { - nextProfile.enter(); - continue outer; - } catch (RedoException e) { - redoProfile.enter(); - } - } - } - - return n; - } - - } - - @CoreMethod(names = "to_s", maxArgs = 0) - public abstract static class ToSNode extends CoreMethodNode { - - public ToSNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ToSNode(ToSNode prev) { - super(prev); - } - - @Specialization - public RubyString toS(BigInteger value) { - return getContext().makeString(value.toString()); - } - - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ClassNodes.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ClassNodes.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.core; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.ruby.nodes.call.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -@CoreClass(name = "Class") -public abstract class ClassNodes { - - @CoreMethod(names = "===", minArgs = 1, maxArgs = 1) - public abstract static class ContainsInstanceNode extends CoreMethodNode { - - public ContainsInstanceNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ContainsInstanceNode(ContainsInstanceNode prev) { - super(prev); - } - - @Specialization - public boolean containsInstance(RubyClass rubyClass, RubyBasicObject instance) { - return instance.getRubyClass().assignableTo(rubyClass); - } - } - - @CoreMethod(names = "new", needsBlock = true, isSplatted = true) - public abstract static class NewNode extends CoreMethodNode { - - @Child protected DispatchHeadNode initialize; - - public NewNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - initialize = adoptChild(new DispatchHeadNode(context, getSourceSection(), "initialize", false)); - } - - public NewNode(NewNode prev) { - super(prev); - initialize = adoptChild(prev.initialize); - } - - @Specialization - public RubyBasicObject newInstance(VirtualFrame frame, RubyClass rubyClass, Object[] args, @SuppressWarnings("unused") UndefinedPlaceholder block) { - return doNewInstance(frame, rubyClass, args, null); - } - - @Specialization - public RubyBasicObject newInstance(VirtualFrame frame, RubyClass rubyClass, Object[] args, RubyProc block) { - return doNewInstance(frame, rubyClass, args, block); - } - - private RubyBasicObject doNewInstance(VirtualFrame frame, RubyClass rubyClass, Object[] args, RubyProc block) { - final RubyBasicObject instance = rubyClass.newInstance(); - initialize.dispatch(frame, instance, block, args); - return instance; - } - - } - - @CoreMethod(names = "to_s", maxArgs = 0) - public abstract static class ToSNode extends CoreMethodNode { - - public ToSNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ToSNode(ToSNode prev) { - super(prev); - } - - @Specialization - public RubyString toS(RubyClass rubyClass) { - return getContext().makeString(rubyClass.getName()); - } - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ComparableNodes.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ComparableNodes.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,158 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.core; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.ruby.nodes.call.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -@CoreClass(name = "Comparable") -public abstract class ComparableNodes { - - public abstract static class ComparableCoreMethodNode extends CoreMethodNode { - - @Child protected DispatchHeadNode compareNode; - - public ComparableCoreMethodNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - compareNode = adoptChild(new DispatchHeadNode(context, getSourceSection(), "<=>", false)); - } - - public ComparableCoreMethodNode(ComparableCoreMethodNode prev) { - super(prev); - compareNode = adoptChild(prev.compareNode); - } - - public int compare(VirtualFrame frame, RubyBasicObject receiverObject, Object comparedTo) { - return (int) compareNode.dispatch(frame, receiverObject, null, comparedTo); - } - - } - - @CoreMethod(names = "<", isModuleMethod = true, minArgs = 1, maxArgs = 1) - public abstract static class LessNode extends ComparableCoreMethodNode { - - public LessNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public LessNode(LessNode prev) { - super(prev); - } - - @Specialization - public boolean less(VirtualFrame frame, RubyBasicObject self, Object comparedTo) { - return compare(frame, self, comparedTo) < 0; - } - - } - - @CoreMethod(names = "<=", isModuleMethod = true, minArgs = 1, maxArgs = 1) - public abstract static class LessEqualNode extends ComparableCoreMethodNode { - - public LessEqualNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public LessEqualNode(LessEqualNode prev) { - super(prev); - } - - @Specialization - public boolean lessEqual(VirtualFrame frame, RubyBasicObject self, Object comparedTo) { - return compare(frame, self, comparedTo) <= 0; - } - - } - - @CoreMethod(names = "==", isModuleMethod = true, minArgs = 1, maxArgs = 1) - public abstract static class EqualNode extends ComparableCoreMethodNode { - - public EqualNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public EqualNode(EqualNode prev) { - super(prev); - } - - @Specialization - public boolean equal(VirtualFrame frame, RubyBasicObject self, Object comparedTo) { - if (self == comparedTo) { - return true; - } - - try { - return compare(frame, self, comparedTo) == 0; - } catch (Exception e) { - // Comparable#== catches and ignores all exceptions in <=>, returning false - return false; - } - } - } - - @CoreMethod(names = ">=", isModuleMethod = true, minArgs = 1, maxArgs = 1) - public abstract static class GreaterEqualNode extends ComparableCoreMethodNode { - - public GreaterEqualNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public GreaterEqualNode(GreaterEqualNode prev) { - super(prev); - } - - @Specialization - public boolean greaterEqual(VirtualFrame frame, RubyBasicObject self, Object comparedTo) { - return compare(frame, self, comparedTo) >= 0; - } - - } - - @CoreMethod(names = ">", isModuleMethod = true, minArgs = 1, maxArgs = 1) - public abstract static class GreaterNode extends ComparableCoreMethodNode { - - public GreaterNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public GreaterNode(GreaterNode prev) { - super(prev); - } - - @Specialization - public boolean greater(VirtualFrame frame, RubyBasicObject self, Object comparedTo) { - return compare(frame, self, comparedTo) > 0; - } - - } - - @CoreMethod(names = "between?", isModuleMethod = true, minArgs = 2, maxArgs = 2) - public abstract static class BetweenNode extends ComparableCoreMethodNode { - - public BetweenNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public BetweenNode(BetweenNode prev) { - super(prev); - } - - @Specialization - public boolean between(VirtualFrame frame, RubyBasicObject self, Object min, Object max) { - return !(compare(frame, self, min) < 0 || compare(frame, self, max) > 0); - } - - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ContinuationNodes.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ContinuationNodes.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.core; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; - -@CoreClass(name = "Continuation") -public abstract class ContinuationNodes { - - @CoreMethod(names = "call", isSplatted = true) - public abstract static class CallNode extends CoreMethodNode { - - public CallNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public CallNode(CallNode prev) { - super(prev); - } - - @Specialization - public Object call(RubyContinuation continuation, Object[] args) { - continuation.call(args); - return null; - } - - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/CoreClass.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/CoreClass.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,20 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.core; - -import java.lang.annotation.*; - -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -public @interface CoreClass { - - String name(); - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/CoreMethod.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/CoreMethod.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.core; - -import java.lang.annotation.*; - -import com.oracle.truffle.ruby.runtime.methods.*; - -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -public @interface CoreMethod { - - String[] names(); - - boolean isModuleMethod() default false; - - boolean needsSelf() default true; - - boolean isSplatted() default false; - - boolean needsBlock() default false; - - boolean appendCallNode() default false; - - int minArgs() default Arity.NO_MINIMUM; - - int maxArgs() default Arity.NO_MAXIMUM; - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/CoreMethodNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/CoreMethodNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.core; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; - -@NodeChild(value = "arguments", type = RubyNode[].class) -public abstract class CoreMethodNode extends RubyNode { - - public CoreMethodNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public CoreMethodNode(CoreMethodNode prev) { - super(prev); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/CoreMethodNodeManager.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/CoreMethodNodeManager.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,217 +0,0 @@ -/* - * Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.core; - -import java.util.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.nodes.control.*; -import com.oracle.truffle.ruby.nodes.debug.*; -import com.oracle.truffle.ruby.nodes.methods.arguments.*; -import com.oracle.truffle.ruby.nodes.objects.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.methods.*; - -public abstract class CoreMethodNodeManager { - - /** - * Register all the nodes that represent core methods as methods with their respective classes, - * given the Object class object, which should already be initialized with all the core classes. - */ - public static void addMethods(RubyClass rubyObjectClass) { - addMethods(rubyObjectClass, getMethods()); - } - - public static void addMethods(RubyClass rubyObjectClass, List methods) { - // Same as above, but allows passing of a specific list of core methods. - // This allows extending Truffle-Ruby with non-standard Core Method. - for (MethodDetails methodDetails : methods) { - addMethod(rubyObjectClass, methodDetails); - } - } - - /** - * Collect up all the core method nodes. Abstracted to allow the SVM to implement at compile - * type. - */ - public static List getMethods() { - final List methods = new ArrayList<>(); - getMethods(methods, ArrayNodesFactory.getFactories()); - getMethods(methods, BasicObjectNodesFactory.getFactories()); - getMethods(methods, BignumNodesFactory.getFactories()); - getMethods(methods, ClassNodesFactory.getFactories()); - getMethods(methods, ContinuationNodesFactory.getFactories()); - getMethods(methods, ComparableNodesFactory.getFactories()); - getMethods(methods, DirNodesFactory.getFactories()); - getMethods(methods, ExceptionNodesFactory.getFactories()); - getMethods(methods, FalseClassNodesFactory.getFactories()); - getMethods(methods, FiberNodesFactory.getFactories()); - getMethods(methods, FileNodesFactory.getFactories()); - getMethods(methods, FixnumNodesFactory.getFactories()); - getMethods(methods, FloatNodesFactory.getFactories()); - getMethods(methods, HashNodesFactory.getFactories()); - getMethods(methods, KernelNodesFactory.getFactories()); - getMethods(methods, MainNodesFactory.getFactories()); - getMethods(methods, MatchDataNodesFactory.getFactories()); - getMethods(methods, MathNodesFactory.getFactories()); - getMethods(methods, ModuleNodesFactory.getFactories()); - getMethods(methods, NilClassNodesFactory.getFactories()); - getMethods(methods, ObjectNodesFactory.getFactories()); - getMethods(methods, ObjectSpaceNodesFactory.getFactories()); - getMethods(methods, ProcessNodesFactory.getFactories()); - getMethods(methods, ProcNodesFactory.getFactories()); - getMethods(methods, RangeNodesFactory.getFactories()); - getMethods(methods, RegexpNodesFactory.getFactories()); - getMethods(methods, SignalNodesFactory.getFactories()); - getMethods(methods, StringNodesFactory.getFactories()); - getMethods(methods, StructNodesFactory.getFactories()); - getMethods(methods, SymbolNodesFactory.getFactories()); - getMethods(methods, ThreadNodesFactory.getFactories()); - getMethods(methods, TimeNodesFactory.getFactories()); - getMethods(methods, TrueClassNodesFactory.getFactories()); - getMethods(methods, DebugNodesFactory.getFactories()); - return methods; - } - - /** - * Collect up the core methods created by a factory. - */ - public static void getMethods(List methods, List> nodeFactories) { - for (NodeFactory nodeFactory : nodeFactories) { - final GeneratedBy generatedBy = nodeFactory.getClass().getAnnotation(GeneratedBy.class); - final Class nodeClass = generatedBy.value(); - final CoreClass classAnnotation = nodeClass.getEnclosingClass().getAnnotation(CoreClass.class); - final CoreMethod methodAnnotation = nodeClass.getAnnotation(CoreMethod.class); - methods.add(new MethodDetails(classAnnotation, methodAnnotation, nodeFactory)); - } - } - - /** - * Take a core method node factory, the annotations for the class and method, and add it as a - * method on the correct class. - */ - private static void addMethod(RubyClass rubyObjectClass, MethodDetails methodDetails) { - assert rubyObjectClass != null; - assert methodDetails != null; - - final RubyContext context = rubyObjectClass.getContext(); - - RubyModule module; - - if (methodDetails.getClassAnnotation().name().equals("main")) { - module = context.getCoreLibrary().getMainObject().getSingletonClass(); - } else { - module = (RubyModule) rubyObjectClass.lookupConstant(methodDetails.getClassAnnotation().name()); - } - - assert module != null : methodDetails.getClassAnnotation().name(); - - final List names = Arrays.asList(methodDetails.getMethodAnnotation().names()); - assert names.size() >= 1; - - final String canonicalName = names.get(0); - final List aliases = names.subList(1, names.size()); - - final UniqueMethodIdentifier uniqueIdentifier = new UniqueMethodIdentifier(); - final Visibility visibility = Visibility.PUBLIC; - - final RubyRootNode pristineRootNode = makeGenericMethod(context, methodDetails); - final CallTarget callTarget = Truffle.getRuntime().createCallTarget(NodeUtil.cloneNode(pristineRootNode)); - - final String intrinsicName = methodDetails.getClassAnnotation().name() + "#" + canonicalName; - - final InlinableMethodImplementation methodImplementation = new InlinableMethodImplementation(callTarget, null, new FrameDescriptor(), pristineRootNode, true, - methodDetails.getMethodAnnotation().appendCallNode()); - final RubyMethod method = new RubyMethod(pristineRootNode.getSourceSection(), module, uniqueIdentifier, intrinsicName, canonicalName, visibility, false, methodImplementation); - - module.addMethod(method); - - if (methodDetails.getMethodAnnotation().isModuleMethod()) { - module.getSingletonClass().addMethod(method); - } - - for (String alias : aliases) { - final RubyMethod withAlias = method.withNewName(alias); - - module.addMethod(withAlias); - - if (methodDetails.getMethodAnnotation().isModuleMethod()) { - module.getSingletonClass().addMethod(withAlias); - } - } - } - - private static RubyRootNode makeGenericMethod(RubyContext context, MethodDetails methodDetails) { - final SourceSection sourceSection = new CoreSourceSection(methodDetails.getClassAnnotation().name() + "#" + methodDetails.getMethodAnnotation().names()[0]); - - final Arity arity = new Arity(methodDetails.getMethodAnnotation().minArgs(), methodDetails.getMethodAnnotation().maxArgs()); - - final List argumentsNodes = new ArrayList<>(); - - if (methodDetails.getMethodAnnotation().needsSelf()) { - argumentsNodes.add(new SelfNode(context, sourceSection)); - } - - if (methodDetails.getMethodAnnotation().isSplatted()) { - argumentsNodes.add(new ReadAllArgumentsNode(context, sourceSection)); - } else { - assert arity.getMaximum() != Arity.NO_MAXIMUM; - - for (int n = 0; n < arity.getMaximum(); n++) { - argumentsNodes.add(new ReadPreArgumentNode(context, sourceSection, n, true)); - } - } - - if (methodDetails.getMethodAnnotation().needsBlock()) { - argumentsNodes.add(new ReadBlockArgumentNode(context, sourceSection, true)); - } - - final RubyNode methodNode = methodDetails.getNodeFactory().createNode(context, sourceSection, argumentsNodes.toArray(new RubyNode[argumentsNodes.size()])); - final CheckArityNode checkArity = new CheckArityNode(context, sourceSection, arity); - final SequenceNode block = new SequenceNode(context, sourceSection, checkArity, methodNode); - - return new RubyRootNode(sourceSection, null, methodDetails.getClassAnnotation().name() + "#" + methodDetails.getMethodAnnotation().names()[0] + "(core)", block); - } - - public static class MethodDetails { - - private final CoreClass classAnnotation; - private final CoreMethod methodAnnotation; - private final NodeFactory nodeFactory; - - public MethodDetails(CoreClass classAnnotation, CoreMethod methodAnnotation, NodeFactory nodeFactory) { - assert classAnnotation != null; - assert methodAnnotation != null; - assert nodeFactory != null; - this.classAnnotation = classAnnotation; - this.methodAnnotation = methodAnnotation; - this.nodeFactory = nodeFactory; - } - - public CoreClass getClassAnnotation() { - return classAnnotation; - } - - public CoreMethod getMethodAnnotation() { - return methodAnnotation; - } - - public NodeFactory getNodeFactory() { - return nodeFactory; - } - - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/DirNodes.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/DirNodes.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,168 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.core; - -import java.io.*; -import java.nio.file.*; -import java.nio.file.attribute.*; - -import com.oracle.truffle.api.CompilerDirectives.SlowPath; -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.core.array.*; - -@CoreClass(name = "Dir") -public abstract class DirNodes { - - @CoreMethod(names = "[]", isModuleMethod = true, needsSelf = false, minArgs = 1, maxArgs = 1) - public abstract static class GlobNode extends CoreMethodNode { - - public GlobNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public GlobNode(GlobNode prev) { - super(prev); - } - - @Specialization - public RubyArray glob(RubyString glob) { - return glob(getContext(), glob.toString()); - } - - @SlowPath - private static RubyArray glob(final RubyContext context, String glob) { - /* - * Globbing is quite complicated. We've implemented a subset of the functionality that - * satisfies MSpec, but it will likely break for anyone else. - */ - - context.implementationMessage("globbing %s", glob); - - String absoluteGlob; - - if (!glob.startsWith("/")) { - absoluteGlob = new File(".", glob).getAbsolutePath().toString(); - } else { - absoluteGlob = glob; - } - - // Get the first star - - final int firstStar = absoluteGlob.indexOf('*'); - assert firstStar >= 0; - - // Walk back from that to the first / before that star - - int prefixLength = firstStar; - - while (prefixLength > 0 && absoluteGlob.charAt(prefixLength) == File.separatorChar) { - prefixLength--; - } - - final String prefix = absoluteGlob.substring(0, prefixLength - 1); - - final PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:" + absoluteGlob.substring(prefixLength)); - - final RubyArray array = new RubyArray(context.getCoreLibrary().getArrayClass()); - - try { - Files.walkFileTree(FileSystems.getDefault().getPath(prefix), new SimpleFileVisitor() { - - @Override - public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - if (matcher.matches(file)) { - array.push(context.makeString(file.toString())); - } - - return FileVisitResult.CONTINUE; - } - - }); - } catch (IOException e) { - throw new RuntimeException(e); - } - - return array; - } - - } - - @CoreMethod(names = "chdir", isModuleMethod = true, needsSelf = false, needsBlock = true, minArgs = 1, maxArgs = 1) - public abstract static class ChdirNode extends YieldingCoreMethodNode { - - public ChdirNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ChdirNode(ChdirNode prev) { - super(prev); - } - - @Specialization - public Object chdir(VirtualFrame frame, RubyString path, RubyProc block) { - final RubyContext context = getContext(); - - final String previous = context.getCurrentDirectory(); - context.setCurrentDirectory(path.toString()); - - if (block != null) { - try { - return yield(frame, block, path); - } finally { - context.setCurrentDirectory(previous); - } - } else { - return 0; - } - } - - } - - @CoreMethod(names = {"exist?", "exists?"}, isModuleMethod = true, needsSelf = false, maxArgs = 1) - public abstract static class ExistsNode extends CoreMethodNode { - - public ExistsNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ExistsNode(ExistsNode prev) { - super(prev); - } - - @Specialization - public boolean exists(RubyString path) { - return new File(path.toString()).isDirectory(); - } - - } - - @CoreMethod(names = "pwd", isModuleMethod = true, needsSelf = false, maxArgs = 0) - public abstract static class PwdNode extends CoreMethodNode { - - public PwdNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public PwdNode(PwdNode prev) { - super(prev); - } - - @Specialization - public RubyString pwd() { - return getContext().makeString(getContext().getCurrentDirectory()); - } - - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ExceptionNodes.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ExceptionNodes.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.core; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.core.array.*; - -@CoreClass(name = "Exception") -public abstract class ExceptionNodes { - - @CoreMethod(names = "initialize", minArgs = 0, maxArgs = 1) - public abstract static class InitializeNode extends CoreMethodNode { - - public InitializeNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public InitializeNode(InitializeNode prev) { - super(prev); - } - - @Specialization - public NilPlaceholder initialize(RubyException exception, @SuppressWarnings("unused") UndefinedPlaceholder message) { - exception.initialize(getContext().makeString(" ")); - return NilPlaceholder.INSTANCE; - } - - @Specialization - public NilPlaceholder initialize(RubyException exception, RubyString message) { - exception.initialize(message); - return NilPlaceholder.INSTANCE; - } - - } - - @CoreMethod(names = "backtrace", needsSelf = false, maxArgs = 0) - public abstract static class BacktraceNode extends CoreMethodNode { - - public BacktraceNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public BacktraceNode(BacktraceNode prev) { - super(prev); - } - - @Specialization - public RubyArray backtrace() { - return new RubyArray(getContext().getCoreLibrary().getArrayClass()); - } - - } - - @CoreMethod(names = "message", maxArgs = 0) - public abstract static class MessageNode extends CoreMethodNode { - - public MessageNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public MessageNode(MessageNode prev) { - super(prev); - } - - @Specialization - public RubyString message(RubyException exception) { - return exception.getMessage(); - } - - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/FalseClassNodes.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/FalseClassNodes.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,97 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.core; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; - -@CoreClass(name = "FalseClass") -public abstract class FalseClassNodes { - - @CoreMethod(names = "!", needsSelf = false, maxArgs = 0) - public abstract static class NotNode extends CoreMethodNode { - - public NotNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public NotNode(NotNode prev) { - super(prev); - } - - @Specialization - public boolean not() { - return true; - } - - } - - @CoreMethod(names = {"==", "===", "=~"}, needsSelf = false, minArgs = 1, maxArgs = 1) - public abstract static class EqualNode extends CoreMethodNode { - - public EqualNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public EqualNode(EqualNode prev) { - super(prev); - } - - @Specialization - public boolean equal(boolean other) { - return !other; - } - - @Specialization - public boolean equal(Object other) { - return other instanceof Boolean && !((boolean) other); - } - - } - - @CoreMethod(names = "^", needsSelf = false, minArgs = 1, maxArgs = 1) - public abstract static class XorNode extends CoreMethodNode { - - public XorNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public XorNode(XorNode prev) { - super(prev); - } - - @Specialization - public boolean xor(boolean other) { - return false ^ other; - } - - } - - @CoreMethod(names = "to_s", needsSelf = false, maxArgs = 0) - public abstract static class ToSNode extends CoreMethodNode { - - public ToSNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ToSNode(ToSNode prev) { - super(prev); - } - - @Specialization - public RubyString toS() { - return getContext().makeString("false"); - } - - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/FiberNodes.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/FiberNodes.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.core; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; - -@CoreClass(name = "Fiber") -public abstract class FiberNodes { - - @CoreMethod(names = "resume", isSplatted = true) - public abstract static class ResumeNode extends CoreMethodNode { - - public ResumeNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ResumeNode(ResumeNode prev) { - super(prev); - } - - @Specialization - public Object resume(RubyFiber fiberBeingResumed, Object[] args) { - final RubyFiber sendingFiber = getContext().getFiberManager().getCurrentFiber(); - - fiberBeingResumed.resume(sendingFiber, args); - - return sendingFiber.waitForResume(); - } - - } - - @CoreMethod(names = "initialize", needsBlock = true, maxArgs = 0) - public abstract static class InitializeNode extends CoreMethodNode { - - public InitializeNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public InitializeNode(InitializeNode prev) { - super(prev); - } - - @Specialization - public NilPlaceholder initialize(RubyFiber fiber, RubyProc block) { - fiber.initialize(block); - return NilPlaceholder.INSTANCE; - } - - } - - @CoreMethod(names = "yield", isModuleMethod = true, needsSelf = false, isSplatted = true) - public abstract static class YieldNode extends CoreMethodNode { - - public YieldNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public YieldNode(YieldNode prev) { - super(prev); - } - - @Specialization - public Object yield(Object[] args) { - final RubyFiber yieldingFiber = getContext().getFiberManager().getCurrentFiber(); - final RubyFiber fiberYieldedTo = yieldingFiber.lastResumedByFiber; - - fiberYieldedTo.resume(yieldingFiber, args); - - return yieldingFiber.waitForResume(); - } - - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/FileNodes.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/FileNodes.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,291 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.core; - -import java.io.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.core.array.*; - -@CoreClass(name = "File") -public abstract class FileNodes { - - @CoreMethod(names = "absolute_path", isModuleMethod = true, needsSelf = false, minArgs = 1, maxArgs = 1) - public abstract static class AbsolutePathNode extends CoreMethodNode { - - public AbsolutePathNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public AbsolutePathNode(AbsolutePathNode prev) { - super(prev); - } - - @Specialization - public RubyString absolutePath(RubyString path) { - return getContext().makeString(new File(path.toString()).getAbsolutePath()); - } - - } - - @CoreMethod(names = "close", maxArgs = 0) - public abstract static class CloseNode extends CoreMethodNode { - - public CloseNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public CloseNode(CloseNode prev) { - super(prev); - } - - @Specialization - public NilPlaceholder close(RubyFile file) { - file.close(); - return NilPlaceholder.INSTANCE; - } - - } - - @CoreMethod(names = "directory?", isModuleMethod = true, needsSelf = false, maxArgs = 1) - public abstract static class DirectoryNode extends CoreMethodNode { - - public DirectoryNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public DirectoryNode(DirectoryNode prev) { - super(prev); - } - - @Specialization - public boolean directory(RubyString path) { - return new File(path.toString()).isDirectory(); - } - - } - - @CoreMethod(names = "dirname", isModuleMethod = true, needsSelf = false, minArgs = 1, maxArgs = 1) - public abstract static class DirnameNode extends CoreMethodNode { - - public DirnameNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public DirnameNode(DirnameNode prev) { - super(prev); - } - - @Specialization - public RubyString dirname(RubyString path) { - final String parent = new File(path.toString()).getParent(); - - if (parent == null) { - return getContext().makeString("."); - } else { - return getContext().makeString(parent); - } - } - - } - - @CoreMethod(names = "each_line", needsBlock = true, maxArgs = 0) - public abstract static class EachLineNode extends YieldingCoreMethodNode { - - public EachLineNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public EachLineNode(EachLineNode prev) { - super(prev); - } - - @Specialization - public NilPlaceholder eachLine(VirtualFrame frame, RubyFile file, RubyProc block) { - final RubyContext context = getContext(); - - // TODO(cs): this buffered reader may consume too much - - final BufferedReader lineReader = new BufferedReader(file.getReader()); - - while (true) { - String line; - - try { - line = lineReader.readLine(); - } catch (IOException e) { - throw new RuntimeException(e); - } - - if (line == null) { - break; - } - - yield(frame, block, context.makeString(line)); - } - - return NilPlaceholder.INSTANCE; - } - - } - - @CoreMethod(names = {"exist?", "exists?"}, isModuleMethod = true, needsSelf = false, minArgs = 1, maxArgs = 1) - public abstract static class ExistsNode extends CoreMethodNode { - - public ExistsNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ExistsNode(ExistsNode prev) { - super(prev); - } - - @Specialization - public boolean exists(RubyString path) { - return new File(path.toString()).isFile(); - } - - } - - @CoreMethod(names = "executable?", isModuleMethod = true, needsSelf = false, minArgs = 1, maxArgs = 1) - public abstract static class ExecutableNode extends CoreMethodNode { - - public ExecutableNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ExecutableNode(ExecutableNode prev) { - super(prev); - } - - @Specialization - public boolean executable(RubyString path) { - return new File(path.toString()).canExecute(); - } - - } - - @CoreMethod(names = "expand_path", isModuleMethod = true, needsSelf = false, minArgs = 1, maxArgs = 2) - public abstract static class ExpandPathNode extends CoreMethodNode { - - public ExpandPathNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ExpandPathNode(ExpandPathNode prev) { - super(prev); - } - - @Specialization - public RubyString expandPath(RubyString path, @SuppressWarnings("unused") UndefinedPlaceholder dir) { - return getContext().makeString(RubyFile.expandPath(path.toString())); - } - - @Specialization - public RubyString expandPath(RubyString path, RubyString dir) { - return getContext().makeString(RubyFile.expandPath(path.toString(), dir.toString())); - } - - } - - @CoreMethod(names = "file?", isModuleMethod = true, needsSelf = false, minArgs = 1, maxArgs = 1) - public abstract static class FileNode extends CoreMethodNode { - - public FileNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public FileNode(FileNode prev) { - super(prev); - } - - @Specialization - public boolean file(RubyString path) { - return new File(path.toString()).isFile(); - } - - } - - @CoreMethod(names = "join", isModuleMethod = true, needsSelf = false, isSplatted = true) - public abstract static class JoinNode extends CoreMethodNode { - - public JoinNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public JoinNode(JoinNode prev) { - super(prev); - } - - @Specialization - public RubyString join(Object[] parts) { - return getContext().makeString(RubyArray.join(parts, File.separator)); - } - } - - @CoreMethod(names = "open", isModuleMethod = true, needsSelf = false, needsBlock = true, minArgs = 2, maxArgs = 2) - public abstract static class OpenNode extends YieldingCoreMethodNode { - - public OpenNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public OpenNode(OpenNode prev) { - super(prev); - } - - @Specialization - public Object open(VirtualFrame frame, RubyString fileName, RubyString mode, RubyProc block) { - final RubyFile file = RubyFile.open(getContext(), fileName.toString(), mode.toString()); - - if (block != null) { - try { - yield(frame, block, file); - } finally { - file.close(); - } - } - - return file; - } - - } - - @CoreMethod(names = "write", maxArgs = 0) - public abstract static class WriteNode extends CoreMethodNode { - - public WriteNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public WriteNode(WriteNode prev) { - super(prev); - } - - @Specialization - public NilPlaceholder write(RubyFile file, RubyString string) { - try { - final Writer writer = file.getWriter(); - writer.write(string.toString()); - writer.flush(); - } catch (IOException e) { - throw new RuntimeException(e); - } - - return NilPlaceholder.INSTANCE; - } - - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/FixnumNodes.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/FixnumNodes.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,889 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.core; - -import java.math.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.utilities.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.control.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.core.array.*; - -@CoreClass(name = "Fixnum") -public abstract class FixnumNodes { - - @CoreMethod(names = "+@", maxArgs = 0) - public abstract static class PosNode extends CoreMethodNode { - - public PosNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public PosNode(PosNode prev) { - super(prev); - } - - @Specialization - public int pos(int value) { - return value; - } - - } - - @CoreMethod(names = "-@", maxArgs = 0) - public abstract static class NegNode extends CoreMethodNode { - - public NegNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public NegNode(NegNode prev) { - super(prev); - } - - @Specialization(rewriteOn = ArithmeticException.class) - public int neg(int value) { - return ExactMath.subtractExact(0, value); - } - - @Specialization - public BigInteger negWithOverflow(int value) { - return BigInteger.valueOf(value).negate(); - } - - } - - @CoreMethod(names = "+", minArgs = 1, maxArgs = 1) - public abstract static class AddNode extends CoreMethodNode { - - public AddNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public AddNode(AddNode prev) { - super(prev); - } - - @Specialization(rewriteOn = ArithmeticException.class) - public int add(int a, int b) { - return ExactMath.addExact(a, b); - } - - @Specialization - public Object addWithOverflow(int a, int b) { - return GeneralConversions.fixnumOrBignum(BigInteger.valueOf(a).add(BigInteger.valueOf(b))); - } - - @Specialization - public double add(int a, double b) { - return a + b; - } - - @Specialization - public Object add(int a, BigInteger b) { - return GeneralConversions.fixnumOrBignum(BigInteger.valueOf(a).add(b)); - } - - } - - @CoreMethod(names = "-", minArgs = 1, maxArgs = 1) - public abstract static class SubNode extends CoreMethodNode { - - public SubNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public SubNode(SubNode prev) { - super(prev); - } - - @Specialization(rewriteOn = ArithmeticException.class) - public int sub(int a, int b) { - return ExactMath.subtractExact(a, b); - } - - @Specialization - public Object subWithOverflow(int a, int b) { - return GeneralConversions.fixnumOrBignum(BigInteger.valueOf(a).subtract(BigInteger.valueOf(b))); - } - - @Specialization - public double sub(int a, double b) { - return a - b; - } - - @Specialization - public Object sub(int a, BigInteger b) { - return GeneralConversions.fixnumOrBignum(BigInteger.valueOf(a).subtract(b)); - } - - } - - @CoreMethod(names = "*", minArgs = 1, maxArgs = 1) - public abstract static class MulNode extends CoreMethodNode { - - public MulNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public MulNode(MulNode prev) { - super(prev); - } - - @Specialization(rewriteOn = ArithmeticException.class) - public int mul(int a, int b) { - return ExactMath.multiplyExact(a, b); - } - - @Specialization - public Object mulWithOverflow(int a, int b) { - return GeneralConversions.fixnumOrBignum(BigInteger.valueOf(a).multiply(BigInteger.valueOf(b))); - } - - @Specialization - public double mul(int a, double b) { - return a * b; - } - - @Specialization - public Object mul(int a, BigInteger b) { - return GeneralConversions.fixnumOrBignum(BigInteger.valueOf(a).multiply(b)); - } - - } - - @CoreMethod(names = "**", minArgs = 1, maxArgs = 1) - public abstract static class PowNode extends CoreMethodNode { - - public PowNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public PowNode(PowNode prev) { - super(prev); - } - - @Specialization - public Object pow(int a, int b) { - return GeneralConversions.fixnumOrBignum(BigInteger.valueOf(a).pow(b)); - } - - @Specialization - public double pow(int a, double b) { - return Math.pow(a, b); - } - - @Specialization - public Object pow(int a, BigInteger b) { - final BigInteger bigA = BigInteger.valueOf(a); - - BigInteger result = BigInteger.ONE; - - for (BigInteger n = BigInteger.ZERO; b.compareTo(b) < 0; n = n.add(BigInteger.ONE)) { - result = result.multiply(bigA); - } - - return result; - } - - } - - @CoreMethod(names = "/", minArgs = 1, maxArgs = 1) - public abstract static class DivNode extends CoreMethodNode { - - public DivNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public DivNode(DivNode prev) { - super(prev); - } - - @Specialization - public int div(int a, int b) { - return a / b; - } - - @Specialization - public double div(int a, double b) { - return a / b; - } - - @Specialization - public int div(@SuppressWarnings("unused") int a, @SuppressWarnings("unused") BigInteger b) { - return 0; - } - } - - @CoreMethod(names = "%", minArgs = 1, maxArgs = 1) - public abstract static class ModNode extends CoreMethodNode { - - public ModNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ModNode(ModNode prev) { - super(prev); - } - - @Specialization - public int mod(int a, int b) { - return a % b; - } - - @Specialization - public double mod(@SuppressWarnings("unused") int a, @SuppressWarnings("unused") double b) { - throw new UnsupportedOperationException(); - } - - @Specialization - public BigInteger mod(@SuppressWarnings("unused") int a, BigInteger b) { - return b; - } - } - - @CoreMethod(names = "divmod", minArgs = 1, maxArgs = 1) - public abstract static class DivModNode extends CoreMethodNode { - - public DivModNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public DivModNode(DivModNode prev) { - super(prev); - } - - @Specialization - public RubyArray divMod(int a, int b) { - int q; - - if (b < 0) { - if (a < 0) { - q = -a / -b; - } else { - q = -(a / -b); - } - } else { - if (a < 0) { - q = -(-a / b); - } else { - q = a / b; - } - } - - int r = a - q * b; - - if ((r < 0 && b > 0) || (r > 0 && b < 0)) { - r += b; - q -= 1; - } - - final FixnumImmutablePairArrayStore store = new FixnumImmutablePairArrayStore(q, r); - return new RubyArray(getContext().getCoreLibrary().getArrayClass(), store); - } - - @Specialization - public RubyArray divMod(@SuppressWarnings("unused") int a, @SuppressWarnings("unused") double b) { - throw new UnsupportedOperationException(); - } - - @Specialization - public RubyArray divMod(int a, BigInteger b) { - return RubyBignum.divMod(getContext(), BigInteger.valueOf(a), b); - } - } - - @CoreMethod(names = "<", minArgs = 1, maxArgs = 1) - public abstract static class LessNode extends CoreMethodNode { - - public LessNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public LessNode(LessNode prev) { - super(prev); - } - - @Specialization - public boolean less(int a, int b) { - return a < b; - } - - @Specialization - public boolean less(int a, double b) { - return a < b; - } - - @Specialization - public boolean less(int a, BigInteger b) { - return BigInteger.valueOf(a).compareTo(b) < 0; - } - } - - @CoreMethod(names = "<=", minArgs = 1, maxArgs = 1) - public abstract static class LessEqualNode extends CoreMethodNode { - - public LessEqualNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public LessEqualNode(LessEqualNode prev) { - super(prev); - } - - @Specialization - public boolean lessEqual(int a, int b) { - return a <= b; - } - - @Specialization - public boolean lessEqual(int a, double b) { - return a <= b; - } - - @Specialization - public boolean lessEqual(int a, BigInteger b) { - return BigInteger.valueOf(a).compareTo(b) <= 0; - } - } - - @CoreMethod(names = {"==", "==="}, minArgs = 1, maxArgs = 1) - public abstract static class EqualNode extends CoreMethodNode { - - public EqualNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public EqualNode(EqualNode prev) { - super(prev); - } - - @Specialization - public boolean equal(int a, int b) { - return a == b; - } - - @Specialization - public boolean equal(int a, double b) { - return a == b; - } - - @Specialization - public boolean equal(int a, BigInteger b) { - return BigInteger.valueOf(a).compareTo(b) == 0; - } - } - - @CoreMethod(names = "<=>", minArgs = 1, maxArgs = 1) - public abstract static class CompareNode extends CoreMethodNode { - - public CompareNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public CompareNode(CompareNode prev) { - super(prev); - } - - @Specialization - public int compare(int a, int b) { - return Integer.compare(a, b); - } - - @Specialization - public int compare(int a, double b) { - return Double.compare(a, b); - } - - @Specialization - public int compare(int a, BigInteger b) { - return BigInteger.valueOf(a).compareTo(b); - } - } - - @CoreMethod(names = "!=", minArgs = 1, maxArgs = 1) - public abstract static class NotEqualNode extends CoreMethodNode { - - public NotEqualNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public NotEqualNode(NotEqualNode prev) { - super(prev); - } - - @Specialization - public boolean notEqual(int a, int b) { - return a != b; - } - - @Specialization - public boolean notEqual(int a, double b) { - return a != b; - } - - @Specialization - public boolean notEqual(int a, BigInteger b) { - return BigInteger.valueOf(a).compareTo(b) != 0; - } - } - - @CoreMethod(names = ">=", minArgs = 1, maxArgs = 1) - public abstract static class GreaterEqualNode extends CoreMethodNode { - - public GreaterEqualNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public GreaterEqualNode(GreaterEqualNode prev) { - super(prev); - } - - @Specialization - public boolean greaterEqual(int a, int b) { - return a >= b; - } - - @Specialization - public boolean greaterEqual(int a, double b) { - return a >= b; - } - - @Specialization - public boolean greaterEqual(int a, BigInteger b) { - return BigInteger.valueOf(a).compareTo(b) >= 0; - } - } - - @CoreMethod(names = ">", minArgs = 1, maxArgs = 1) - public abstract static class GreaterNode extends CoreMethodNode { - - public GreaterNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public GreaterNode(GreaterNode prev) { - super(prev); - } - - @Specialization - public boolean equal(int a, int b) { - return a > b; - } - - @Specialization - public boolean equal(int a, double b) { - return a > b; - } - - @Specialization - public boolean equal(int a, BigInteger b) { - return BigInteger.valueOf(a).compareTo(b) > 0; - } - } - - @CoreMethod(names = "~", maxArgs = 0) - public abstract static class ComplementNode extends CoreMethodNode { - - public ComplementNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ComplementNode(ComplementNode prev) { - super(prev); - } - - @Specialization - public int complement(int n) { - return ~n; - } - - } - - @CoreMethod(names = "&", minArgs = 1, maxArgs = 1) - public abstract static class BitAndNode extends CoreMethodNode { - - public BitAndNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public BitAndNode(BitAndNode prev) { - super(prev); - } - - @Specialization - public int bitAnd(int a, int b) { - return a & b; - } - - @Specialization - public Object bitAnd(int a, BigInteger b) { - return GeneralConversions.fixnumOrBignum(BigInteger.valueOf(a).and(b)); - } - } - - @CoreMethod(names = "|", minArgs = 1, maxArgs = 1) - public abstract static class BitOrNode extends CoreMethodNode { - - public BitOrNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public BitOrNode(BitOrNode prev) { - super(prev); - } - - @Specialization - public int bitOr(int a, int b) { - return a | b; - } - - @Specialization - public Object bitOr(int a, BigInteger b) { - return GeneralConversions.fixnumOrBignum(BigInteger.valueOf(a).or(b)); - } - } - - @CoreMethod(names = "^", minArgs = 1, maxArgs = 1) - public abstract static class BitXOrNode extends CoreMethodNode { - - public BitXOrNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public BitXOrNode(BitXOrNode prev) { - super(prev); - } - - @Specialization - public int bitXOr(int a, int b) { - return a ^ b; - } - - @Specialization - public Object bitXOr(int a, BigInteger b) { - return GeneralConversions.fixnumOrBignum(BigInteger.valueOf(a).xor(b)); - } - } - - @CoreMethod(names = "<<", minArgs = 1, maxArgs = 1) - public abstract static class LeftShiftNode extends CoreMethodNode { - - public LeftShiftNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public LeftShiftNode(LeftShiftNode prev) { - super(prev); - } - - @Specialization - public Object leftShift(int a, int b) { - if (b > 0) { - if (RubyFixnum.SIZE - Integer.numberOfLeadingZeros(a) + b > RubyFixnum.SIZE - 1) { - return GeneralConversions.fixnumOrBignum(BigInteger.valueOf(a).shiftLeft(b)); - } else { - return a << b; - } - } else { - if (-b >= Integer.SIZE) { - return 0; - } else { - return a >> -b; - } - } - } - - } - - @CoreMethod(names = ">>", minArgs = 1, maxArgs = 1) - public abstract static class RightShiftNode extends CoreMethodNode { - - public RightShiftNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public RightShiftNode(RightShiftNode prev) { - super(prev); - } - - @Specialization - public int rightShift(int a, int b) { - if (b > 0) { - return a >> b; - } else { - if (-b >= RubyFixnum.SIZE) { - return 0; - } else { - return a >> -b; - } - } - } - - } - - @CoreMethod(names = "[]", minArgs = 1, maxArgs = 1) - public abstract static class GetIndexNode extends CoreMethodNode { - - public GetIndexNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public GetIndexNode(GetIndexNode prev) { - super(prev); - } - - @Specialization - public int getIndex(int self, int index) { - if ((self & (1 << index)) == 0) { - return 0; - } else { - return 1; - } - } - - } - - @CoreMethod(names = "chr", maxArgs = 0) - public abstract static class ChrNode extends CoreMethodNode { - - public ChrNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ChrNode(ChrNode prev) { - super(prev); - } - - @Specialization - public RubyString chr(int n) { - // TODO(CS): not sure about encoding here - return getContext().makeString((char) n); - } - - } - - @CoreMethod(names = "inspect", maxArgs = 0) - public abstract static class InpsectNode extends CoreMethodNode { - - public InpsectNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public InpsectNode(InpsectNode prev) { - super(prev); - } - - @Specialization - public RubyString inspect(int n) { - return getContext().makeString(Integer.toString(n)); - } - - } - - @CoreMethod(names = "nonzero?", maxArgs = 0) - public abstract static class NonZeroNode extends CoreMethodNode { - - public NonZeroNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public NonZeroNode(NonZeroNode prev) { - super(prev); - } - - @Specialization - public Object nonZero(int value) { - if (value == 0) { - return false; - } else { - return value; - } - } - - } - - @CoreMethod(names = "size", needsSelf = false, maxArgs = 0) - public abstract static class SizeNode extends CoreMethodNode { - - public SizeNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public SizeNode(SizeNode prev) { - super(prev); - } - - @Specialization - public int size() { - return Integer.SIZE / Byte.SIZE; - } - - } - - @CoreMethod(names = "step", needsBlock = true, minArgs = 2, maxArgs = 2) - public abstract static class StepNode extends YieldingCoreMethodNode { - - public StepNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public StepNode(StepNode prev) { - super(prev); - } - - @Specialization - public NilPlaceholder step(VirtualFrame frame, int from, int to, int step, RubyProc block) { - for (int i = from; i <= to; i += step) { - yield(frame, block, i); - } - - return NilPlaceholder.INSTANCE; - } - - } - - @CoreMethod(names = "times", needsBlock = true, maxArgs = 0) - public abstract static class TimesNode extends YieldingCoreMethodNode { - - private final BranchProfile breakProfile = new BranchProfile(); - private final BranchProfile nextProfile = new BranchProfile(); - private final BranchProfile redoProfile = new BranchProfile(); - - public TimesNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public TimesNode(TimesNode prev) { - super(prev); - } - - @Specialization - public Object times(VirtualFrame frame, int n, RubyProc block) { - outer: for (int i = 0; i < n; i++) { - while (true) { - try { - yield(frame, block, i); - continue outer; - } catch (BreakException e) { - breakProfile.enter(); - return e.getResult(); - } catch (NextException e) { - nextProfile.enter(); - continue outer; - } catch (RedoException e) { - redoProfile.enter(); - } - } - } - - return n; - } - - } - - @CoreMethod(names = {"to_i", "to_int"}, maxArgs = 0) - public abstract static class ToINode extends CoreMethodNode { - - public ToINode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ToINode(ToINode prev) { - super(prev); - } - - @Specialization - public int toI(int n) { - return n; - } - - } - - @CoreMethod(names = "to_f", maxArgs = 0) - public abstract static class ToFNode extends CoreMethodNode { - - public ToFNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ToFNode(ToFNode prev) { - super(prev); - } - - @Specialization - public double toF(int n) { - return n; - } - - } - - @CoreMethod(names = "to_s", maxArgs = 0) - public abstract static class ToSNode extends CoreMethodNode { - - public ToSNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ToSNode(ToSNode prev) { - super(prev); - } - - @Specialization - public RubyString toS(int n) { - return getContext().makeString(Integer.toString(n)); - } - - } - - @CoreMethod(names = "upto", needsBlock = true, minArgs = 1, maxArgs = 1) - public abstract static class UpToNode extends YieldingCoreMethodNode { - - private final BranchProfile breakProfile = new BranchProfile(); - private final BranchProfile nextProfile = new BranchProfile(); - private final BranchProfile redoProfile = new BranchProfile(); - - public UpToNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public UpToNode(UpToNode prev) { - super(prev); - } - - @Specialization - public Object upto(VirtualFrame frame, int from, int to, RubyProc block) { - outer: for (int i = from; i <= to; i++) { - while (true) { - try { - yield(frame, block, i); - continue outer; - } catch (BreakException e) { - breakProfile.enter(); - return e.getResult(); - } catch (NextException e) { - nextProfile.enter(); - continue outer; - } catch (RedoException e) { - redoProfile.enter(); - } - } - } - - return NilPlaceholder.INSTANCE; - } - - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/FloatNodes.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/FloatNodes.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,493 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.core; - -import java.math.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.core.array.*; - -@CoreClass(name = "Float") -public abstract class FloatNodes { - - @CoreMethod(names = "+@", maxArgs = 0) - public abstract static class PosNode extends CoreMethodNode { - - public PosNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public PosNode(PosNode prev) { - super(prev); - } - - @Specialization - public double pos(double value) { - return value; - } - - } - - @CoreMethod(names = "-@", maxArgs = 0) - public abstract static class NegNode extends CoreMethodNode { - - public NegNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public NegNode(NegNode prev) { - super(prev); - } - - @Specialization - public double neg(double value) { - return -value; - } - - } - - @CoreMethod(names = "+", minArgs = 1, maxArgs = 1) - public abstract static class AddNode extends CoreMethodNode { - - public AddNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public AddNode(AddNode prev) { - super(prev); - } - - @Specialization - public double add(double a, int b) { - return a + b; - } - - @Specialization - public double add(double a, double b) { - return a + b; - } - - @Specialization - public double add(double a, BigInteger b) { - return a + b.doubleValue(); - } - - } - - @CoreMethod(names = "-", minArgs = 1, maxArgs = 1) - public abstract static class SubNode extends CoreMethodNode { - - public SubNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public SubNode(SubNode prev) { - super(prev); - } - - @Specialization - public double sub(double a, int b) { - return a - b; - } - - @Specialization - public double sub(double a, double b) { - return a - b; - } - - @Specialization - public double sub(double a, BigInteger b) { - return a - b.doubleValue(); - } - - } - - @CoreMethod(names = "*", minArgs = 1, maxArgs = 1) - public abstract static class MulNode extends CoreMethodNode { - - public MulNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public MulNode(MulNode prev) { - super(prev); - } - - @Specialization - public double mul(double a, int b) { - return a * b; - } - - @Specialization - public double mul(double a, double b) { - return a * b; - } - - @Specialization - public double mul(double a, BigInteger b) { - return a * b.doubleValue(); - } - - } - - @CoreMethod(names = "**", minArgs = 1, maxArgs = 1) - public abstract static class PowNode extends CoreMethodNode { - - public PowNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public PowNode(PowNode prev) { - super(prev); - } - - @Specialization - public double mul(double a, int b) { - return Math.pow(a, b); - } - - @Specialization - public double mul(double a, double b) { - return Math.pow(a, b); - } - - @Specialization - public double mul(double a, BigInteger b) { - return Math.pow(a, b.doubleValue()); - } - - } - - @CoreMethod(names = "/", minArgs = 1, maxArgs = 1) - public abstract static class DivNode extends CoreMethodNode { - - public DivNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public DivNode(DivNode prev) { - super(prev); - } - - @Specialization - public double div(double a, int b) { - return a / b; - } - - @Specialization - public double div(double a, double b) { - return a / b; - } - - @Specialization - public double div(double a, BigInteger b) { - return a / b.doubleValue(); - } - - } - - @CoreMethod(names = "%", minArgs = 1, maxArgs = 1) - public abstract static class ModNode extends CoreMethodNode { - - public ModNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ModNode(ModNode prev) { - super(prev); - } - - @Specialization - public double mod(@SuppressWarnings("unused") double a, @SuppressWarnings("unused") int b) { - throw new UnsupportedOperationException(); - } - - @Specialization - public double mod(@SuppressWarnings("unused") double a, @SuppressWarnings("unused") double b) { - throw new UnsupportedOperationException(); - } - - @Specialization - public double mod(@SuppressWarnings("unused") double a, @SuppressWarnings("unused") BigInteger b) { - throw new UnsupportedOperationException(); - } - - } - - @CoreMethod(names = "divmod", minArgs = 1, maxArgs = 1) - public abstract static class DivModNode extends CoreMethodNode { - - public DivModNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public DivModNode(DivModNode prev) { - super(prev); - } - - @Specialization - public RubyArray divMod(@SuppressWarnings("unused") double a, @SuppressWarnings("unused") int b) { - throw new UnsupportedOperationException(); - } - - @Specialization - public RubyArray divMod(@SuppressWarnings("unused") double a, @SuppressWarnings("unused") double b) { - throw new UnsupportedOperationException(); - } - - @Specialization - public RubyArray divMod(@SuppressWarnings("unused") double a, @SuppressWarnings("unused") BigInteger b) { - throw new UnsupportedOperationException(); - } - - } - - @CoreMethod(names = "<", minArgs = 1, maxArgs = 1) - public abstract static class LessNode extends CoreMethodNode { - - public LessNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public LessNode(LessNode prev) { - super(prev); - } - - @Specialization - public boolean less(double a, int b) { - return a < b; - } - - @Specialization - public boolean less(double a, double b) { - return a < b; - } - - @Specialization - public boolean less(double a, BigInteger b) { - return BigInteger.valueOf((long) a).compareTo(b) < 0; - } - } - - @CoreMethod(names = "<=", minArgs = 1, maxArgs = 1) - public abstract static class LessEqualNode extends CoreMethodNode { - - public LessEqualNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public LessEqualNode(LessEqualNode prev) { - super(prev); - } - - @Specialization - public boolean lessEqual(double a, int b) { - return a <= b; - } - - @Specialization - public boolean lessEqual(double a, double b) { - return a <= b; - } - - @Specialization - public boolean lessEqual(double a, BigInteger b) { - return BigInteger.valueOf((long) a).compareTo(b) <= 0; - } - } - - @CoreMethod(names = "==", minArgs = 1, maxArgs = 1) - public abstract static class EqualNode extends CoreMethodNode { - - public EqualNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public EqualNode(EqualNode prev) { - super(prev); - } - - @Specialization - public boolean equal(double a, int b) { - return a == b; - } - - @Specialization - public boolean equal(double a, double b) { - return a == b; - } - - @Specialization - public boolean equal(double a, BigInteger b) { - return BigInteger.valueOf((long) a).compareTo(b) == 0; - } - } - - @CoreMethod(names = "!=", minArgs = 1, maxArgs = 1) - public abstract static class NotEqualNode extends CoreMethodNode { - - public NotEqualNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public NotEqualNode(NotEqualNode prev) { - super(prev); - } - - @Specialization - public boolean notEqual(double a, int b) { - return a != b; - } - - @Specialization - public boolean notEqual(double a, double b) { - return a != b; - } - - @Specialization - public boolean notEqual(double a, BigInteger b) { - return BigInteger.valueOf((long) a).compareTo(b) != 0; - } - } - - @CoreMethod(names = ">=", minArgs = 1, maxArgs = 1) - public abstract static class GreaterEqualNode extends CoreMethodNode { - - public GreaterEqualNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public GreaterEqualNode(GreaterEqualNode prev) { - super(prev); - } - - @Specialization - public boolean greaterEqual(double a, int b) { - return a >= b; - } - - @Specialization - public boolean greaterEqual(double a, double b) { - return a >= b; - } - - @Specialization - public boolean greaterEqual(double a, BigInteger b) { - return BigInteger.valueOf((long) a).compareTo(b) >= 0; - } - } - - @CoreMethod(names = ">", minArgs = 1, maxArgs = 1) - public abstract static class GreaterNode extends CoreMethodNode { - - public GreaterNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public GreaterNode(GreaterNode prev) { - super(prev); - } - - @Specialization - public boolean equal(double a, int b) { - return a > b; - } - - @Specialization - public boolean equal(double a, double b) { - return a > b; - } - - @Specialization - public boolean equal(double a, BigInteger b) { - return BigInteger.valueOf((long) a).compareTo(b) > 0; - } - } - - @CoreMethod(names = "abs", maxArgs = 0) - public abstract static class AbsNode extends CoreMethodNode { - - public AbsNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public AbsNode(AbsNode prev) { - super(prev); - } - - @Specialization - public double abs(double n) { - return Math.abs(n); - } - - } - - @CoreMethod(names = "inspect", maxArgs = 0) - public abstract static class InpsectNode extends CoreMethodNode { - - public InpsectNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public InpsectNode(InpsectNode prev) { - super(prev); - } - - @Specialization - public RubyString inspect(double n) { - return getContext().makeString(Double.toString(n)); - } - - } - - @CoreMethod(names = "nonzero?", maxArgs = 0) - public abstract static class NonZeroNode extends CoreMethodNode { - - public NonZeroNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public NonZeroNode(NonZeroNode prev) { - super(prev); - } - - @Specialization - public Object nonZero(double value) { - if (value == 0) { - return false; - } else { - return value; - } - } - - } - - @CoreMethod(names = "to_s", maxArgs = 0) - public abstract static class ToSNode extends CoreMethodNode { - - public ToSNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ToSNode(ToSNode prev) { - super(prev); - } - - @Specialization - public RubyString toS(double value) { - return getContext().makeString(Double.toString(value)); - } - - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/HashNodes.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/HashNodes.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,308 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.core; - -import java.util.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.core.array.*; - -@CoreClass(name = "Hash") -public abstract class HashNodes { - - @CoreMethod(names = "[]", isModuleMethod = true, needsSelf = false, isSplatted = true) - public abstract static class ConstructNode extends CoreMethodNode { - - public ConstructNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ConstructNode(ConstructNode prev) { - super(prev); - } - - @Specialization - public RubyHash construct(Object[] args) { - final RubyHash hash = new RubyHash(getContext().getCoreLibrary().getHashClass()); - - if (args.length == 1) { - final RubyArray array = (RubyArray) args[0]; - - for (int n = 0; n < array.size(); n++) { - final RubyArray keyValue = (RubyArray) array.get(n); - hash.put(keyValue.get(0), keyValue.get(1)); - } - } else { - if (args.length % 2 != 0) { - // TODO(CS): figure out what error to throw here - throw new UnsupportedOperationException(); - } - - for (int n = 0; n < args.length; n += 2) { - hash.put(args[n], args[n + 1]); - } - } - - return hash; - } - - } - - @CoreMethod(names = "[]", minArgs = 1, maxArgs = 1) - public abstract static class GetIndexNode extends CoreMethodNode { - - public GetIndexNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public GetIndexNode(GetIndexNode prev) { - super(prev); - } - - @Specialization - public Object construct(VirtualFrame frame, RubyHash hash, Object index) { - final Object value = hash.get(index); - - if (value == null) { - if (hash.defaultBlock == null) { - return NilPlaceholder.INSTANCE; - } else { - return hash.defaultBlock.call(frame.pack(), hash, index); - } - } else { - return value; - } - } - - } - - @CoreMethod(names = "[]=", minArgs = 2, maxArgs = 2) - public abstract static class SetIndexNode extends CoreMethodNode { - - public SetIndexNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public SetIndexNode(SetIndexNode prev) { - super(prev); - } - - @Specialization - public Object construct(RubyHash hash, Object index, Object value) { - hash.put(index, value); - return value; - } - - } - - @CoreMethod(names = "delete", minArgs = 1, maxArgs = 1) - public abstract static class DeleteNode extends CoreMethodNode { - - public DeleteNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public DeleteNode(DeleteNode prev) { - super(prev); - } - - @Specialization - public Object delete(RubyHash hash, Object index) { - hash.checkFrozen(); - - final Object value = hash.getMap().remove(index); - - if (value == null) { - return NilPlaceholder.INSTANCE; - } else { - return value; - } - } - - } - - @CoreMethod(names = "each", needsBlock = true, maxArgs = 0) - public abstract static class EachNode extends YieldingCoreMethodNode { - - public EachNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public EachNode(EachNode prev) { - super(prev); - } - - @Specialization - public NilPlaceholder each(VirtualFrame frame, RubyHash hash, RubyProc block) { - for (Map.Entry entry : hash.storage.entrySet()) { - yield(frame, block, entry.getKey(), entry.getValue()); - } - - return NilPlaceholder.INSTANCE; - } - - } - - @CoreMethod(names = "empty?", maxArgs = 0) - public abstract static class EmptyNode extends CoreMethodNode { - - public EmptyNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public EmptyNode(EmptyNode prev) { - super(prev); - } - - @Specialization - public boolean empty(RubyHash hash) { - return hash.storage.isEmpty(); - } - - } - - @CoreMethod(names = "initialize", needsBlock = true, maxArgs = 0) - public abstract static class InitializeNode extends CoreMethodNode { - - public InitializeNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public InitializeNode(InitializeNode prev) { - super(prev); - } - - @Specialization - public NilPlaceholder initialize(RubyHash hash, @SuppressWarnings("unused") UndefinedPlaceholder block) { - hash.initialize(null); - return NilPlaceholder.INSTANCE; - } - - @Specialization - public NilPlaceholder initialize(RubyHash hash, RubyProc block) { - hash.initialize(block); - return NilPlaceholder.INSTANCE; - } - - } - - @CoreMethod(names = {"map", "collect"}, needsBlock = true, maxArgs = 0) - public abstract static class MapNode extends YieldingCoreMethodNode { - - public MapNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public MapNode(MapNode prev) { - super(prev); - } - - @Specialization - public RubyArray map(VirtualFrame frame, RubyHash hash, RubyProc block) { - final RubyArray result = new RubyArray(getContext().getCoreLibrary().getArrayClass()); - - for (Map.Entry entry : hash.storage.entrySet()) { - result.push(yield(frame, block, entry.getKey(), entry.getValue())); - } - - return result; - } - - } - - @CoreMethod(names = "key?", minArgs = 1, maxArgs = 1) - public abstract static class KeyNode extends CoreMethodNode { - - public KeyNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public KeyNode(KeyNode prev) { - super(prev); - } - - @Specialization - public boolean key(RubyHash hash, Object key) { - return hash.storage.containsKey(key); - } - - } - - @CoreMethod(names = "keys", maxArgs = 0) - public abstract static class KeysNode extends CoreMethodNode { - - public KeysNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public KeysNode(KeysNode prev) { - super(prev); - } - - @Specialization - public RubyArray keys(RubyHash hash) { - final RubyArray array = new RubyArray(getContext().getCoreLibrary().getArrayClass()); - - for (Object key : hash.storage.keySet()) { - array.push(key); - } - - return array; - } - - } - - @CoreMethod(names = "size", maxArgs = 0) - public abstract static class SizeNode extends CoreMethodNode { - - public SizeNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public SizeNode(SizeNode prev) { - super(prev); - } - - @Specialization - public int size(RubyHash hash) { - return hash.storage.size(); - } - - } - - @CoreMethod(names = "values", maxArgs = 0) - public abstract static class ValuesNode extends CoreMethodNode { - - public ValuesNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ValuesNode(ValuesNode prev) { - super(prev); - } - - @Specialization - public RubyArray values(RubyHash hash) { - final RubyArray array = new RubyArray(getContext().getCoreLibrary().getArrayClass()); - - for (Object value : hash.storage.values()) { - array.push(value); - } - - return array; - } - - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/InterpolatedStringNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/InterpolatedStringNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.core; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; - -/** - * A list of expressions to build up into a string. - */ -@NodeInfo(shortName = "interpolated-string") -public final class InterpolatedStringNode extends RubyNode { - - @CompilationFinal private int expectedLength = 64; - - @Children protected final RubyNode[] children; - - public InterpolatedStringNode(RubyContext context, SourceSection sourceSection, RubyNode[] children) { - super(context, sourceSection); - this.children = adoptChildren(children); - } - - @ExplodeLoop - @Override - public Object execute(VirtualFrame frame) { - final StringBuilder builder = new StringBuilder(expectedLength); - - for (int n = 0; n < children.length; n++) { - builder.append(children[n].execute(frame).toString()); - } - - if (builder.length() > expectedLength) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - expectedLength = builder.length() * 2; - } - - return getContext().makeString(builder.toString()); - } - - @ExplodeLoop - @Override - public void executeVoid(VirtualFrame frame) { - for (int n = 0; n < children.length; n++) { - children[n].executeVoid(frame); - } - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/KernelNodes.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/KernelNodes.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,797 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.core; - -import java.io.*; -import java.math.*; -import java.util.*; - -import com.oracle.truffle.api.CompilerDirectives.SlowPath; -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.nodes.call.*; -import com.oracle.truffle.ruby.nodes.cast.*; -import com.oracle.truffle.ruby.nodes.control.*; -import com.oracle.truffle.ruby.nodes.literal.*; -import com.oracle.truffle.ruby.nodes.yield.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.control.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.core.array.*; -import com.oracle.truffle.ruby.runtime.objects.*; -import com.oracle.truffle.ruby.runtime.subsystems.*; - -@CoreClass(name = "Kernel") -public abstract class KernelNodes { - - @CoreMethod(names = "Array", isModuleMethod = true, needsSelf = false, isSplatted = true) - public abstract static class ArrayNode extends CoreMethodNode { - - public ArrayNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ArrayNode(ArrayNode prev) { - super(prev); - } - - @Specialization - public RubyArray array(Object[] args) { - if (args.length == 1 && args[0] instanceof RubyArray) { - return (RubyArray) args[0]; - } else { - return RubyArray.specializedFromObjects(getContext().getCoreLibrary().getArrayClass(), args); - } - } - - } - - @CoreMethod(names = "at_exit", isModuleMethod = true, needsSelf = false, needsBlock = true, maxArgs = 0) - public abstract static class AtExitNode extends CoreMethodNode { - - public AtExitNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public AtExitNode(AtExitNode prev) { - super(prev); - } - - @Specialization - public Object atExit(RubyProc block) { - getContext().getAtExitManager().add(block); - return NilPlaceholder.INSTANCE; - } - } - - @CoreMethod(names = "binding", isModuleMethod = true, needsSelf = true, maxArgs = 0) - public abstract static class BindingNode extends CoreMethodNode { - - public BindingNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public BindingNode(BindingNode prev) { - super(prev); - } - - @Specialization - public Object binding(VirtualFrame frame, Object self) { - return new RubyBinding(getContext().getCoreLibrary().getBindingClass(), self, frame.getCaller().unpack().materialize()); - } - } - - @CoreMethod(names = "block_given?", isModuleMethod = true, needsSelf = false, maxArgs = 0) - public abstract static class BlockGivenNode extends CoreMethodNode { - - public BlockGivenNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public BlockGivenNode(BlockGivenNode prev) { - super(prev); - } - - @Specialization - public boolean blockGiven(VirtualFrame frame) { - return frame.getCaller().unpack().getArguments(RubyArguments.class).getBlock() != null; - } - } - - // TODO(CS): should hide this in a feature - - @CoreMethod(names = "callcc", isModuleMethod = true, needsSelf = false, needsBlock = true, maxArgs = 0) - public abstract static class CallccNode extends CoreMethodNode { - - public CallccNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public CallccNode(CallccNode prev) { - super(prev); - } - - @Specialization - public Object callcc(RubyProc block) { - final RubyContext context = getContext(); - - if (block == null) { - // TODO(CS): should really have acceptsBlock and needsBlock to do this automatically - throw new RaiseException(context.getCoreLibrary().localJumpError("no block given")); - } - - final RubyContinuation continuation = new RubyContinuation(context.getCoreLibrary().getContinuationClass()); - return continuation.enter(block); - } - } - - @CoreMethod(names = "catch", isModuleMethod = true, needsSelf = false, needsBlock = true, minArgs = 1, maxArgs = 1) - public abstract static class CatchNode extends YieldingCoreMethodNode { - - public CatchNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public CatchNode(CatchNode prev) { - super(prev); - } - - @Specialization - public Object doCatch(VirtualFrame frame, Object tag, RubyProc block) { - try { - return yield(frame, block); - } catch (ThrowException e) { - if (e.getTag().equals(tag)) { - // TODO(cs): unset rather than set to Nil? - getContext().getCoreLibrary().getGlobalVariablesObject().setInstanceVariable("$!", NilPlaceholder.INSTANCE); - return e.getValue(); - } else { - throw e; - } - } - } - } - - @CoreMethod(names = "eval", isModuleMethod = true, needsSelf = false, minArgs = 1, maxArgs = 2) - public abstract static class EvalNode extends CoreMethodNode { - - public EvalNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public EvalNode(EvalNode prev) { - super(prev); - } - - @Specialization - public Object eval(RubyString source, @SuppressWarnings("unused") UndefinedPlaceholder binding) { - return getContext().eval(source.toString()); - } - - @Specialization - public Object eval(RubyString source, RubyBinding binding) { - return getContext().eval(source.toString(), binding); - } - - } - - @CoreMethod(names = "exec", isModuleMethod = true, needsSelf = false, minArgs = 1, isSplatted = true) - public abstract static class ExecNode extends CoreMethodNode { - - public ExecNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ExecNode(ExecNode prev) { - super(prev); - } - - @Specialization - public Object require(Object[] args) { - final String[] commandLine = new String[args.length]; - - for (int n = 0; n < args.length; n++) { - commandLine[n] = args[n].toString(); - } - - exec(getContext(), commandLine); - - return null; - } - - @SlowPath - private static void exec(RubyContext context, String[] commandLine) { - context.implementationMessage("starting child process to simulate exec: "); - - for (int n = 0; n < commandLine.length; n++) { - if (n > 0) { - System.err.print(" "); - } - - System.err.print(commandLine[n]); - } - - final ProcessBuilder builder = new ProcessBuilder(commandLine); - builder.inheritIO(); - - final RubyHash env = (RubyHash) context.getCoreLibrary().getObjectClass().lookupConstant("ENV"); - - for (Map.Entry entry : env.getMap().entrySet()) { - builder.environment().put(entry.getKey().toString(), entry.getValue().toString()); - } - - Process process; - - try { - process = builder.start(); - } catch (IOException e) { - // TODO(cs): proper Ruby exception - throw new RuntimeException(e); - } - - int exitCode; - - while (true) { - try { - exitCode = process.waitFor(); - break; - } catch (InterruptedException e) { - continue; - } - } - - context.implementationMessage("child process simulating exec finished"); - - System.exit(exitCode); - } - - } - - @CoreMethod(names = "exit", isModuleMethod = true, needsSelf = false, minArgs = 0, maxArgs = 1) - public abstract static class ExitNode extends CoreMethodNode { - - public ExitNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ExitNode(ExitNode prev) { - super(prev); - } - - @Specialization - public Object exit(@SuppressWarnings("unused") UndefinedPlaceholder exitCode) { - getContext().shutdown(); - System.exit(0); - return null; - } - - @Specialization - public Object exit(int exitCode) { - getContext().shutdown(); - System.exit(exitCode); - return null; - } - - } - - @CoreMethod(names = "gets", isModuleMethod = true, needsSelf = false, maxArgs = 0) - public abstract static class GetsNode extends CoreMethodNode { - - public GetsNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public GetsNode(GetsNode prev) { - super(prev); - } - - @Specialization - public RubyString gets(VirtualFrame frame) { - final RubyContext context = getContext(); - - final ThreadManager threadManager = context.getThreadManager(); - - RubyString line; - - try { - final RubyThread runningThread = threadManager.leaveGlobalLock(); - - try { - line = context.makeString(context.getConfiguration().getInputReader().readLine("")); - } finally { - threadManager.enterGlobalLock(runningThread); - } - } catch (IOException e) { - throw new RuntimeException(e); - } - - // Set the local variable $_ in the caller - - final Frame unpacked = frame.getCaller().unpack(); - final FrameSlot slot = unpacked.getFrameDescriptor().findFrameSlot("$_"); - - if (slot != null) { - unpacked.setObject(slot, line); - } - - return line; - } - } - - @CoreMethod(names = "Integer", isModuleMethod = true, needsSelf = false, minArgs = 1, maxArgs = 1) - public abstract static class IntegerNode extends CoreMethodNode { - - @Child protected DispatchHeadNode toInt; - - public IntegerNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - toInt = adoptChild(new DispatchHeadNode(context, getSourceSection(), "to_int", false)); - } - - public IntegerNode(IntegerNode prev) { - super(prev); - toInt = adoptChild(prev.toInt); - } - - @Specialization - public int integer(int value) { - return value; - } - - @Specialization - public BigInteger integer(BigInteger value) { - return value; - } - - @Specialization - public int integer(double value) { - return (int) value; - } - - @Specialization - public Object integer(RubyString value) { - return value.toInteger(); - } - - @Specialization - public Object integer(VirtualFrame frame, Object value) { - return toInt.dispatch(frame, value, null); - } - - } - - @CoreMethod(names = "lambda", isModuleMethod = true, needsBlock = true, maxArgs = 0) - public abstract static class LambdaNode extends CoreMethodNode { - - public LambdaNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public LambdaNode(LambdaNode prev) { - super(prev); - } - - @Specialization - public RubyProc proc(Object self, RubyProc block) { - return new RubyProc(getContext().getCoreLibrary().getProcClass(), RubyProc.Type.LAMBDA, self, block, block.getMethod()); - - } - } - - @CoreMethod(names = "load", isModuleMethod = true, needsSelf = false, minArgs = 1, maxArgs = 1) - public abstract static class LoadNode extends CoreMethodNode { - - public LoadNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public LoadNode(LoadNode prev) { - super(prev); - } - - @Specialization - public boolean load(RubyString file) { - getContext().loadFile(file.toString()); - return true; - } - } - - @CoreMethod(names = "loop", isModuleMethod = true, needsSelf = false, maxArgs = 0) - public abstract static class LoopNode extends CoreMethodNode { - - @Child protected WhileNode whileNode; - - public LoopNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - whileNode = adoptChild(new WhileNode(context, sourceSection, BooleanCastNodeFactory.create(context, sourceSection, new BooleanLiteralNode(context, sourceSection, true)), new YieldNode( - context, getSourceSection(), new RubyNode[]{}))); - } - - public LoopNode(LoopNode prev) { - super(prev); - whileNode = adoptChild(prev.whileNode); - } - - @Specialization - public Object loop(VirtualFrame frame) { - return whileNode.execute(frame); - } - } - - @CoreMethod(names = "print", isModuleMethod = true, needsSelf = false, isSplatted = true) - public abstract static class PrintNode extends CoreMethodNode { - - public PrintNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public PrintNode(PrintNode prev) { - super(prev); - } - - @Specialization - public NilPlaceholder print(Object[] args) { - final RubyContext context = getContext(); - final ThreadManager threadManager = context.getThreadManager(); - - final RubyThread runningThread = threadManager.leaveGlobalLock(); - - try { - for (Object arg : args) { - /* - * TODO(cs): If it's a RubyString and made up of bytes, just write the bytes out - * - using toString will mess up the encoding. We need to stop using toString - * everywhere, and write our own bytes, possibly using JRuby's library for this. - */ - - if (arg instanceof RubyString && !((RubyString) arg).isFromJavaString()) { - try { - context.getConfiguration().getStandardOut().write(((RubyString) arg).getBytes()); - } catch (IOException e) { - throw new RuntimeException(e); - } - } else { - context.getConfiguration().getStandardOut().print(arg); - } - } - } finally { - threadManager.enterGlobalLock(runningThread); - } - - return NilPlaceholder.INSTANCE; - } - } - - @CoreMethod(names = "printf", isModuleMethod = true, needsSelf = false, isSplatted = true) - public abstract static class PrintfNode extends CoreMethodNode { - - public PrintfNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public PrintfNode(PrintfNode prev) { - super(prev); - } - - @Specialization - public NilPlaceholder printf(Object[] args) { - final RubyContext context = getContext(); - final ThreadManager threadManager = context.getThreadManager(); - - if (args.length > 0) { - final String format = ((RubyString) args[0]).toString(); - final List values = Arrays.asList(args).subList(1, args.length); - - final RubyThread runningThread = threadManager.leaveGlobalLock(); - - try { - StringFormatter.format(context.getConfiguration().getStandardOut(), format, values); - } finally { - threadManager.enterGlobalLock(runningThread); - } - } - - return NilPlaceholder.INSTANCE; - } - } - - /* - * Kernel#pretty_inspect is normally part of stdlib, in pp.rb, but we aren't able to execute - * that file yet. Instead we implement a very simple version here, which is the solution - * suggested by RubySpec. - */ - - @CoreMethod(names = "pretty_inspect", maxArgs = 0) - public abstract static class PrettyInspectNode extends CoreMethodNode { - - @Child protected DispatchHeadNode toS; - - public PrettyInspectNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - toS = adoptChild(new DispatchHeadNode(context, getSourceSection(), "to_s", false)); - } - - public PrettyInspectNode(PrettyInspectNode prev) { - super(prev); - toS = adoptChild(prev.toS); - } - - @Specialization - public Object prettyInspect(VirtualFrame frame, Object self) { - return toS.dispatch(frame, self, null); - - } - } - - @CoreMethod(names = "proc", isModuleMethod = true, needsBlock = true, maxArgs = 0) - public abstract static class ProcNode extends CoreMethodNode { - - public ProcNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ProcNode(ProcNode prev) { - super(prev); - } - - @Specialization - public RubyProc proc(Object self, RubyProc block) { - return new RubyProc(getContext().getCoreLibrary().getProcClass(), RubyProc.Type.PROC, self, block, block.getMethod()); - - } - } - - @CoreMethod(names = "puts", isModuleMethod = true, needsSelf = false, isSplatted = true) - public abstract static class PutsNode extends CoreMethodNode { - - public PutsNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public PutsNode(PutsNode prev) { - super(prev); - } - - @ExplodeLoop - @Specialization - public NilPlaceholder puts(Object[] args) { - final RubyContext context = getContext(); - final ThreadManager threadManager = context.getThreadManager(); - final PrintStream standardOut = context.getConfiguration().getStandardOut(); - - final RubyThread runningThread = threadManager.leaveGlobalLock(); - - try { - if (args.length == 0) { - standardOut.println(); - } else { - for (int n = 0; n < args.length; n++) { - puts(context, standardOut, args[n]); - } - } - } finally { - threadManager.enterGlobalLock(runningThread); - } - - return NilPlaceholder.INSTANCE; - } - - @SlowPath - private void puts(RubyContext context, PrintStream standardOut, Object value) { - if (value instanceof RubyArray) { - final RubyArray array = (RubyArray) value; - - for (int n = 0; n < array.size(); n++) { - puts(context, standardOut, array.get(n)); - } - } else { - // TODO(CS): slow path send - standardOut.println(context.getCoreLibrary().box(value).send("to_s", null)); - } - } - - } - - @CoreMethod(names = "raise", isModuleMethod = true, needsSelf = false, minArgs = 1, maxArgs = 2) - public abstract static class RaiseNode extends CoreMethodNode { - - @Child protected DispatchHeadNode initialize; - - public RaiseNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - initialize = adoptChild(new DispatchHeadNode(context, getSourceSection(), "initialize", false)); - } - - public RaiseNode(RaiseNode prev) { - super(prev); - initialize = adoptChild(prev.initialize); - } - - @Specialization(order = 1) - public Object raise(VirtualFrame frame, RubyString message, @SuppressWarnings("unused") UndefinedPlaceholder undefined) { - return raise(frame, getContext().getCoreLibrary().getRuntimeErrorClass(), message); - } - - @Specialization(order = 2) - public Object raise(VirtualFrame frame, RubyClass exceptionClass, @SuppressWarnings("unused") UndefinedPlaceholder undefined) { - return raise(frame, exceptionClass, getContext().makeString("")); - } - - @Specialization(order = 3) - public Object raise(VirtualFrame frame, RubyClass exceptionClass, RubyString message) { - final RubyBasicObject exception = exceptionClass.newInstance(); - initialize.dispatch(frame, exception, null, message); - throw new RaiseException(exception); - } - - } - - @CoreMethod(names = "require", isModuleMethod = true, needsSelf = false, minArgs = 1, maxArgs = 1) - public abstract static class RequireNode extends CoreMethodNode { - - public RequireNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public RequireNode(RequireNode prev) { - super(prev); - } - - @Specialization - public boolean require(RubyString feature) { - try { - getContext().getFeatureManager().require(feature.toString()); - } catch (IOException e) { - throw new RuntimeException(e); - } - - return true; - } - } - - @CoreMethod(names = "set_trace_func", isModuleMethod = true, needsSelf = false, minArgs = 1, maxArgs = 1) - public abstract static class SetTraceFuncNode extends CoreMethodNode { - - public SetTraceFuncNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public SetTraceFuncNode(SetTraceFuncNode prev) { - super(prev); - } - - @Specialization - public NilPlaceholder setTraceFunc(NilPlaceholder proc) { - getContext().getTraceManager().setTraceProc(null); - return proc; - } - - @Specialization - public RubyProc setTraceFunc(RubyProc proc) { - getContext().getTraceManager().setTraceProc(proc); - return proc; - } - - } - - @CoreMethod(names = "String", isModuleMethod = true, needsSelf = false, minArgs = 1, maxArgs = 1) - public abstract static class StringNode extends CoreMethodNode { - - @Child protected DispatchHeadNode toS; - - public StringNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - toS = adoptChild(new DispatchHeadNode(context, getSourceSection(), "to_s", false)); - } - - public StringNode(StringNode prev) { - super(prev); - toS = adoptChild(prev.toS); - } - - @Specialization - public RubyString string(int value) { - return getContext().makeString(Integer.toString(value)); - } - - @Specialization - public RubyString string(BigInteger value) { - return getContext().makeString(value.toString()); - } - - @Specialization - public RubyString string(double value) { - return getContext().makeString(Double.toString(value)); - } - - @Specialization - public RubyString string(RubyString value) { - return value; - } - - @Specialization - public Object string(VirtualFrame frame, Object value) { - return toS.dispatch(frame, value, null); - } - - } - - @CoreMethod(names = "sleep", isModuleMethod = true, needsSelf = false, maxArgs = 1) - public abstract static class SleepNode extends CoreMethodNode { - - public SleepNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public SleepNode(SleepNode prev) { - super(prev); - } - - @Specialization - public double sleep(double duration) { - final RubyContext context = getContext(); - - final RubyThread runningThread = context.getThreadManager().leaveGlobalLock(); - - try { - final long start = System.nanoTime(); - - try { - Thread.sleep((long) (duration * 1000)); - } catch (InterruptedException e) { - // Ignore interruption - } - - final long end = System.nanoTime(); - - return (end - start) / 1e9; - } finally { - context.getThreadManager().enterGlobalLock(runningThread); - } - } - - @Specialization - public double sleep(int duration) { - return sleep((double) duration); - } - - } - - @CoreMethod(names = "throw", isModuleMethod = true, needsSelf = false, minArgs = 1, maxArgs = 2) - public abstract static class ThrowNode extends CoreMethodNode { - - public ThrowNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ThrowNode(ThrowNode prev) { - super(prev); - } - - @Specialization - public Object doThrow(Object tag, UndefinedPlaceholder value) { - return doThrow(tag, (Object) value); - } - - @Specialization - public Object doThrow(Object tag, Object value) { - if (value instanceof UndefinedPlaceholder) { - throw new ThrowException(tag, NilPlaceholder.INSTANCE); - } else { - throw new ThrowException(tag, value); - } - } - - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/MainNodes.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/MainNodes.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.core; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; - -@CoreClass(name = "main") -public abstract class MainNodes { - - @CoreMethod(names = "include", isSplatted = true, minArgs = 1) - public abstract static class IncludeNode extends CoreMethodNode { - - public IncludeNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public IncludeNode(IncludeNode prev) { - super(prev); - } - - @Specialization - public NilPlaceholder include(RubyObject main, Object[] args) { - // TODO(cs): copied from Module - but where does this method really come from? - - // Note that we traverse the arguments backwards - - for (int n = args.length - 1; n >= 0; n--) { - if (args[n] instanceof RubyModule) { - final RubyModule included = (RubyModule) args[n]; - - // Note that we do appear to do full method lookup here - included.getLookupNode().lookupMethod("append_features").call(null, included, null, main.getSingletonClass()); - - // TODO(cs): call included hook - } - } - - return NilPlaceholder.INSTANCE; - } - } - - @CoreMethod(names = "to_s", needsSelf = false, maxArgs = 0) - public abstract static class ToSNode extends CoreMethodNode { - - public ToSNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ToSNode(ToSNode prev) { - super(prev); - } - - @Specialization - public RubyString toS() { - return getContext().makeString("main"); - } - - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/MatchDataNodes.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/MatchDataNodes.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.core; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.core.array.*; - -@CoreClass(name = "MatchData") -public abstract class MatchDataNodes { - - @CoreMethod(names = "[]", minArgs = 1, maxArgs = 1) - public abstract static class GetIndexNode extends CoreMethodNode { - - public GetIndexNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public GetIndexNode(GetIndexNode prev) { - super(prev); - } - - @Specialization - public Object getIndex(RubyMatchData matchData, int index) { - return matchData.getValues()[index]; - } - - } - - @CoreMethod(names = "to_a", maxArgs = 0) - public abstract static class ToANode extends CoreMethodNode { - - public ToANode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ToANode(ToANode prev) { - super(prev); - } - - @Specialization - public RubyArray toA(RubyMatchData matchData) { - return RubyArray.specializedFromObjects(getContext().getCoreLibrary().getArrayClass(), matchData.getValues()); - } - - } - - @CoreMethod(names = "values_at", isSplatted = true) - public abstract static class ValuesAtNode extends CoreMethodNode { - - public ValuesAtNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ValuesAtNode(ValuesAtNode prev) { - super(prev); - } - - @Specialization - public RubyArray valuesAt(RubyMatchData matchData, Object[] args) { - final int[] indicies = new int[args.length]; - - for (int n = 0; n < args.length; n++) { - indicies[n] = (int) args[n]; - } - - return RubyArray.specializedFromObjects(getContext().getCoreLibrary().getArrayClass(), matchData.valuesAt(indicies)); - } - - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/MathNodes.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/MathNodes.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.core; - -import java.math.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.ruby.runtime.*; - -@CoreClass(name = "Math") -public abstract class MathNodes { - - @CoreMethod(names = "sqrt", isModuleMethod = true, needsSelf = false, minArgs = 1, maxArgs = 1) - public abstract static class SqrtNode extends CoreMethodNode { - - public SqrtNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public SqrtNode(SqrtNode prev) { - super(prev); - } - - @Specialization - public double sqrt(int a) { - return Math.sqrt(a); - } - - @Specialization - public double sqrt(BigInteger a) { - return Math.sqrt(a.doubleValue()); - } - - @Specialization - public double sqrt(double a) { - return Math.sqrt(a); - } - - } - - @CoreMethod(names = "exp", isModuleMethod = true, needsSelf = false, minArgs = 1, maxArgs = 1) - public abstract static class ExpNode extends CoreMethodNode { - - public ExpNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ExpNode(ExpNode prev) { - super(prev); - } - - @Specialization - public double exp(int a) { - return Math.exp(a); - } - - @Specialization - public double exp(BigInteger a) { - return Math.exp(a.doubleValue()); - } - - @Specialization - public double exp(double a) { - return Math.exp(a); - } - - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ModuleNodes.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ModuleNodes.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,652 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.core; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.nodes.control.*; -import com.oracle.truffle.ruby.nodes.methods.arguments.*; -import com.oracle.truffle.ruby.nodes.objects.*; -import com.oracle.truffle.ruby.nodes.objects.instancevariables.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.RubyParser.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.core.array.*; -import com.oracle.truffle.ruby.runtime.methods.*; - -@CoreClass(name = "Module") -public abstract class ModuleNodes { - - @CoreMethod(names = "alias_method", minArgs = 2, maxArgs = 2) - public abstract static class AliasMethodNode extends CoreMethodNode { - - public AliasMethodNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public AliasMethodNode(AliasMethodNode prev) { - super(prev); - } - - @Specialization - public RubyModule aliasMethod(RubyModule module, RubySymbol newName, RubySymbol oldName) { - module.alias(newName.toString(), oldName.toString()); - return module; - } - } - - @CoreMethod(names = "append_features", minArgs = 1, maxArgs = 1) - public abstract static class AppendFeaturesNode extends CoreMethodNode { - - public AppendFeaturesNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public AppendFeaturesNode(AppendFeaturesNode prev) { - super(prev); - } - - @Specialization - public NilPlaceholder appendFeatures(RubyModule module, RubyModule other) { - module.appendFeatures(other); - return NilPlaceholder.INSTANCE; - } - } - - @CoreMethod(names = "attr_reader", isSplatted = true, appendCallNode = true) - public abstract static class AttrReaderNode extends CoreMethodNode { - - public AttrReaderNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public AttrReaderNode(AttrReaderNode prev) { - super(prev); - } - - @Specialization - public NilPlaceholder attrReader(RubyModule module, Object[] args) { - final Node callSite = (Node) args[args.length - 1]; - final SourceSection sourceSection = callSite.getSourceSection(); - - for (int n = 0; n < args.length - 1; n++) { - attrReader(getContext(), sourceSection, module, args[n].toString()); - } - - return NilPlaceholder.INSTANCE; - } - - public static void attrReader(RubyContext context, SourceSection sourceSection, RubyModule module, String name) { - CompilerDirectives.transferToInterpreter(); - - final CheckArityNode checkArity = new CheckArityNode(context, sourceSection, Arity.NO_ARGS); - - final SelfNode self = new SelfNode(context, sourceSection); - final UninitializedReadInstanceVariableNode readInstanceVariable = new UninitializedReadInstanceVariableNode(context, sourceSection, name, self); - - final SequenceNode block = new SequenceNode(context, sourceSection, checkArity, readInstanceVariable); - - final RubyRootNode pristineRoot = new RubyRootNode(sourceSection, null, name + "(attr_reader)", block); - final CallTarget callTarget = Truffle.getRuntime().createCallTarget(NodeUtil.cloneNode(pristineRoot)); - final InlinableMethodImplementation methodImplementation = new InlinableMethodImplementation(callTarget, null, new FrameDescriptor(), pristineRoot, true, false); - final RubyMethod method = new RubyMethod(sourceSection, module, new UniqueMethodIdentifier(), null, name, Visibility.PUBLIC, false, methodImplementation); - - module.addMethod(method); - } - } - - @CoreMethod(names = "attr_writer", isSplatted = true, appendCallNode = true) - public abstract static class AttrWriterNode extends CoreMethodNode { - - public AttrWriterNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public AttrWriterNode(AttrWriterNode prev) { - super(prev); - } - - @Specialization - public NilPlaceholder attrWriter(RubyModule module, Object[] args) { - final Node callSite = (Node) args[args.length - 1]; - final SourceSection sourceSection = callSite.getSourceSection(); - - for (int n = 0; n < args.length - 1; n++) { - attrWriter(getContext(), sourceSection, module, args[n].toString()); - } - - return NilPlaceholder.INSTANCE; - } - - public static void attrWriter(RubyContext context, SourceSection sourceSection, RubyModule module, String name) { - CompilerDirectives.transferToInterpreter(); - - final CheckArityNode checkArity = new CheckArityNode(context, sourceSection, Arity.ONE_ARG); - - final SelfNode self = new SelfNode(context, sourceSection); - final ReadPreArgumentNode readArgument = new ReadPreArgumentNode(context, sourceSection, 0, false); - final UninitializedWriteInstanceVariableNode writeInstanceVariable = new UninitializedWriteInstanceVariableNode(context, sourceSection, name, self, readArgument); - - final SequenceNode block = new SequenceNode(context, sourceSection, checkArity, writeInstanceVariable); - - final RubyRootNode pristineRoot = new RubyRootNode(sourceSection, null, name + "(attr_writer)", block); - final CallTarget callTarget = Truffle.getRuntime().createCallTarget(NodeUtil.cloneNode(pristineRoot)); - final InlinableMethodImplementation methodImplementation = new InlinableMethodImplementation(callTarget, null, new FrameDescriptor(), pristineRoot, true, false); - final RubyMethod method = new RubyMethod(sourceSection, module, new UniqueMethodIdentifier(), null, name + "=", Visibility.PUBLIC, false, methodImplementation); - - module.addMethod(method); - } - } - - @CoreMethod(names = {"attr_accessor", "attr"}, isSplatted = true, appendCallNode = true) - public abstract static class AttrAccessorNode extends CoreMethodNode { - - public AttrAccessorNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public AttrAccessorNode(AttrAccessorNode prev) { - super(prev); - } - - @Specialization - public NilPlaceholder attrAccessor(RubyModule module, Object[] args) { - final Node callSite = (Node) args[args.length - 1]; - final SourceSection sourceSection = callSite.getSourceSection(); - - for (int n = 0; n < args.length - 1; n++) { - attrAccessor(getContext(), sourceSection, module, args[n].toString()); - } - - return NilPlaceholder.INSTANCE; - } - - public static void attrAccessor(RubyContext context, SourceSection sourceSection, RubyModule module, String name) { - CompilerDirectives.transferToInterpreter(); - AttrReaderNode.attrReader(context, sourceSection, module, name); - AttrWriterNode.attrWriter(context, sourceSection, module, name); - } - - } - - @CoreMethod(names = "class_eval", minArgs = 1, maxArgs = 3) - public abstract static class ClassEvalNode extends CoreMethodNode { - - public ClassEvalNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ClassEvalNode(ClassEvalNode prev) { - super(prev); - } - - @Specialization - public Object classEval(VirtualFrame frame, RubyModule module, RubyString code, @SuppressWarnings("unused") UndefinedPlaceholder file, @SuppressWarnings("unused") UndefinedPlaceholder line) { - final Source source = getContext().getSourceManager().get("(eval)", code.toString()); - return getContext().execute(getContext(), source, ParserContext.MODULE, module, frame.materialize()); - } - - @Specialization - public Object classEval(VirtualFrame frame, RubyModule module, RubyString code, RubyString file, @SuppressWarnings("unused") UndefinedPlaceholder line) { - final Source source = getContext().getSourceManager().get(file.toString(), code.toString()); - return getContext().execute(getContext(), source, ParserContext.MODULE, module, frame.materialize()); - } - - @Specialization - public Object classEval(VirtualFrame frame, RubyModule module, RubyString code, RubyString file, @SuppressWarnings("unused") int line) { - final Source source = getContext().getSourceManager().get(file.toString(), code.toString()); - return getContext().execute(getContext(), source, ParserContext.MODULE, module, frame.materialize()); - } - - } - - @CoreMethod(names = "class_variable_defined?", maxArgs = 0) - public abstract static class ClassVariableDefinedNode extends CoreMethodNode { - - public ClassVariableDefinedNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ClassVariableDefinedNode(ClassVariableDefinedNode prev) { - super(prev); - } - - @Specialization - public boolean isClassVariableDefined(RubyModule module, RubyString name) { - return module.lookupClassVariable(name.toString()) != null; - } - - @Specialization - public boolean isClassVariableDefined(RubyModule module, RubySymbol name) { - return module.lookupClassVariable(name.toString()) != null; - } - - } - - @CoreMethod(names = "constants", maxArgs = 0) - public abstract static class ConstantsNode extends CoreMethodNode { - - public ConstantsNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ConstantsNode(ConstantsNode prev) { - super(prev); - } - - @Specialization - public RubyArray constants(@SuppressWarnings("unused") RubyModule module) { - getContext().implementationMessage("Module#constants returns an empty array"); - return new RubyArray(getContext().getCoreLibrary().getArrayClass()); - } - } - - @CoreMethod(names = "const_defined?", minArgs = 1, maxArgs = 2) - public abstract static class ConstDefinedNode extends CoreMethodNode { - - public ConstDefinedNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ConstDefinedNode(ConstDefinedNode prev) { - super(prev); - } - - @Specialization(order = 1) - public boolean isConstDefined(RubyModule module, RubyString name, @SuppressWarnings("unused") UndefinedPlaceholder inherit) { - return module.lookupConstant(name.toString()) != null; - } - - @Specialization(order = 2) - public boolean isConstDefined(RubyModule module, RubyString name, boolean inherit) { - if (inherit) { - return module.lookupConstant(name.toString()) != null; - } else { - return module.getConstants().containsKey(name.toString()); - } - } - - @Specialization(order = 3) - public boolean isConstDefined(RubyModule module, RubySymbol name, @SuppressWarnings("unused") UndefinedPlaceholder inherit) { - return module.lookupConstant(name.toString()) != null; - } - - public boolean isConstDefined(RubyModule module, RubySymbol name, boolean inherit) { - if (inherit) { - return module.lookupConstant(name.toString()) != null; - } else { - return module.getConstants().containsKey(name.toString()); - } - } - - } - - @CoreMethod(names = "define_method", needsBlock = true, minArgs = 1, maxArgs = 2) - public abstract static class DefineMethodNode extends CoreMethodNode { - - public DefineMethodNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public DefineMethodNode(DefineMethodNode prev) { - super(prev); - } - - @Specialization(order = 1) - public RubyMethod defineMethod(RubyModule module, RubyString name, @SuppressWarnings("unused") UndefinedPlaceholder proc, RubyProc block) { - final RubyMethod method = block.getMethod(); - module.addMethod(method.withNewName(name.toString())); - return method; - } - - @Specialization(order = 2) - public RubyMethod defineMethod(RubyModule module, RubyString name, RubyProc proc, @SuppressWarnings("unused") UndefinedPlaceholder block) { - final RubyMethod method = proc.getMethod(); - module.addMethod(method.withNewName(name.toString())); - return method; - } - - @Specialization(order = 3) - public RubyMethod defineMethod(RubyModule module, RubySymbol name, @SuppressWarnings("unused") UndefinedPlaceholder proc, RubyProc block) { - final RubyMethod method = block.getMethod(); - module.addMethod(method.withNewName(name.toString())); - return method; - } - - @Specialization(order = 4) - public RubyMethod defineMethod(RubyModule module, RubySymbol name, RubyProc proc, @SuppressWarnings("unused") UndefinedPlaceholder block) { - final RubyMethod method = proc.getMethod(); - module.addMethod(method.withNewName(name.toString())); - return method; - } - - } - - @CoreMethod(names = "include", isSplatted = true, minArgs = 1) - public abstract static class IncludeNode extends CoreMethodNode { - - public IncludeNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public IncludeNode(IncludeNode prev) { - super(prev); - } - - @Specialization - public NilPlaceholder include(RubyModule module, Object[] args) { - // Note that we traverse the arguments backwards - - for (int n = args.length - 1; n >= 0; n--) { - if (args[n] instanceof RubyModule) { - final RubyModule included = (RubyModule) args[n]; - - // Note that we do appear to do full method lookup here - included.getLookupNode().lookupMethod("append_features").call(null, included, null, module); - - // TODO(cs): call included hook - } - } - - return NilPlaceholder.INSTANCE; - } - } - - @CoreMethod(names = "method_defined?", minArgs = 1, maxArgs = 2) - public abstract static class MethodDefinedNode extends CoreMethodNode { - - public MethodDefinedNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public MethodDefinedNode(MethodDefinedNode prev) { - super(prev); - } - - @Specialization(order = 1) - public boolean isMethodDefined(RubyModule module, RubyString name, @SuppressWarnings("unused") UndefinedPlaceholder inherit) { - return module.lookupMethod(name.toString()) != null; - } - - @Specialization(order = 2) - public boolean isMethodDefined(RubyModule module, RubyString name, boolean inherit) { - if (inherit) { - return module.lookupMethod(name.toString()) != null; - } else { - return module.getMethods().containsKey(name.toString()); - } - } - - @Specialization(order = 3) - public boolean isMethodDefined(RubyModule module, RubySymbol name, @SuppressWarnings("unused") UndefinedPlaceholder inherit) { - return module.lookupMethod(name.toString()) != null; - } - - public boolean isMethodDefined(RubyModule module, RubySymbol name, boolean inherit) { - if (inherit) { - return module.lookupMethod(name.toString()) != null; - } else { - return module.getMethods().containsKey(name.toString()); - } - } - } - - @CoreMethod(names = "module_eval", minArgs = 1, maxArgs = 3) - public abstract static class ModuleEvalNode extends CoreMethodNode { - - public ModuleEvalNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ModuleEvalNode(ModuleEvalNode prev) { - super(prev); - } - - @Specialization - public RubyModule moduleEval(RubyModule module, RubyString code, @SuppressWarnings("unused") Object file, @SuppressWarnings("unused") Object line) { - module.moduleEval(code.toString()); - return module; - } - } - - @CoreMethod(names = "module_function", isSplatted = true) - public abstract static class ModuleFunctionNode extends CoreMethodNode { - - public ModuleFunctionNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ModuleFunctionNode(ModuleFunctionNode prev) { - super(prev); - } - - @Specialization - public NilPlaceholder moduleFunction(VirtualFrame frame, RubyModule module, Object... args) { - if (args.length == 0) { - final Frame unpacked = frame.getCaller().unpack(); - - final FrameSlot slot = unpacked.getFrameDescriptor().findFrameSlot(RubyModule.MODULE_FUNCTION_FLAG_FRAME_SLOT_ID); - - /* - * setObject, even though it's a boolean, so we can getObject and either get the - * default Nil or the boolean value without triggering deoptimization. - */ - - unpacked.setObject(slot, true); - } else { - for (Object argument : args) { - final String methodName = argument.toString(); - module.getSingletonClass().addMethod(module.lookupMethod(methodName)); - } - } - - return NilPlaceholder.INSTANCE; - } - } - - @CoreMethod(names = "public", isSplatted = true) - public abstract static class PublicNode extends CoreMethodNode { - - public PublicNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public PublicNode(PublicNode prev) { - super(prev); - } - - @Specialization - public RubyModule doPublic(VirtualFrame frame, RubyModule module, Object... args) { - module.visibilityMethod(frame.getCaller(), args, Visibility.PUBLIC); - return module; - } - } - - @CoreMethod(names = "private", isSplatted = true) - public abstract static class PrivateNode extends CoreMethodNode { - - public PrivateNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public PrivateNode(PrivateNode prev) { - super(prev); - } - - @Specialization - public RubyModule doPrivate(VirtualFrame frame, RubyModule module, Object... args) { - module.visibilityMethod(frame.getCaller(), args, Visibility.PRIVATE); - return module; - } - } - - @CoreMethod(names = "private_class_method", isSplatted = true) - public abstract static class PrivateClassMethodNode extends CoreMethodNode { - - public PrivateClassMethodNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public PrivateClassMethodNode(PrivateClassMethodNode prev) { - super(prev); - } - - @Specialization - public RubyModule privateClassMethod(RubyModule module, Object... args) { - final RubyClass moduleSingleton = module.getSingletonClass(); - - for (Object arg : args) { - final RubyMethod method = moduleSingleton.lookupMethod(arg.toString()); - - if (method == null) { - throw new RuntimeException("Couldn't find method " + arg.toString()); - } - - moduleSingleton.addMethod(method.withNewVisibility(Visibility.PRIVATE)); - } - - return module; - } - } - - @CoreMethod(names = "private_constant", isSplatted = true) - public abstract static class PrivateConstantNode extends CoreMethodNode { - - public PrivateConstantNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public PrivateConstantNode(PrivateConstantNode prev) { - super(prev); - } - - @Specialization - public RubyModule privateConstnat(RubyModule module, @SuppressWarnings("unused") Object... args) { - getContext().implementationMessage("private_constant does nothing at the moment"); - return module; - } - } - - @CoreMethod(names = "protected", isSplatted = true) - public abstract static class ProtectedNode extends CoreMethodNode { - - public ProtectedNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ProtectedNode(ProtectedNode prev) { - super(prev); - } - - @Specialization - public RubyModule doProtected(RubyModule module, @SuppressWarnings("unused") Object... args) { - getContext().implementationMessage("protected does nothing at the moment"); - return module; - } - } - - @CoreMethod(names = "remove_class_variable", minArgs = 1, maxArgs = 1) - public abstract static class RemoveClassVariableNode extends CoreMethodNode { - - public RemoveClassVariableNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public RemoveClassVariableNode(RemoveClassVariableNode prev) { - super(prev); - } - - @Specialization - public RubyModule removeClassVariable(RubyModule module, RubyString name) { - module.removeClassVariable(name.toString()); - return module; - } - - @Specialization - public RubyModule removeClassVariable(RubyModule module, RubySymbol name) { - module.removeClassVariable(name.toString()); - return module; - } - - } - - @CoreMethod(names = "remove_method", minArgs = 1, maxArgs = 1) - public abstract static class RemoveMethodNode extends CoreMethodNode { - - public RemoveMethodNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public RemoveMethodNode(RemoveMethodNode prev) { - super(prev); - } - - @Specialization - public RubyModule removeMethod(RubyModule module, RubyString name) { - module.removeMethod(name.toString()); - return module; - } - - @Specialization - public RubyModule removeMethod(RubyModule module, RubySymbol name) { - module.removeMethod(name.toString()); - return module; - } - - } - - @CoreMethod(names = "to_s", maxArgs = 0) - public abstract static class ToSNode extends CoreMethodNode { - - public ToSNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ToSNode(ToSNode prev) { - super(prev); - } - - @Specialization - public RubyString toS(RubyModule module) { - return getContext().makeString(module.getName()); - } - } - - @CoreMethod(names = "undef_method", minArgs = 1, maxArgs = 1) - public abstract static class UndefMethodNode extends CoreMethodNode { - - public UndefMethodNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public UndefMethodNode(UndefMethodNode prev) { - super(prev); - } - - @Specialization - public RubyModule undefMethod(RubyModule module, RubyString name) { - final RubyMethod method = module.lookupMethod(name.toString()); - module.undefMethod(method); - return module; - } - - @Specialization - public RubyModule undefMethod(RubyModule module, RubySymbol name) { - final RubyMethod method = module.lookupMethod(name.toString()); - module.undefMethod(method); - return module; - } - - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/NilClassNodes.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/NilClassNodes.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,141 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.core; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; - -@CoreClass(name = "NilClass") -public abstract class NilClassNodes { - - @CoreMethod(names = "!", needsSelf = false, maxArgs = 0) - public abstract static class NotNode extends CoreMethodNode { - - public NotNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public NotNode(NotNode prev) { - super(prev); - } - - @Specialization - public boolean not() { - return true; - } - } - - @CoreMethod(names = "==", needsSelf = false, minArgs = 1, maxArgs = 1) - public abstract static class EqualNode extends CoreMethodNode { - - public EqualNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public EqualNode(EqualNode prev) { - super(prev); - } - - @Specialization - public boolean equal(Object b) { - return b instanceof NilPlaceholder || b instanceof RubyNilClass; - } - - } - - @CoreMethod(names = "!=", needsSelf = false, minArgs = 1, maxArgs = 1) - public abstract static class NotEqualNode extends CoreMethodNode { - - public NotEqualNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public NotEqualNode(NotEqualNode prev) { - super(prev); - } - - @Specialization - public boolean equal(Object b) { - return !(b instanceof NilPlaceholder || b instanceof RubyNilClass); - } - - } - - @CoreMethod(names = "inspect", needsSelf = false, maxArgs = 0) - public abstract static class InpsectNode extends CoreMethodNode { - - public InpsectNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public InpsectNode(InpsectNode prev) { - super(prev); - } - - @Specialization - public RubyString inspect() { - return getContext().makeString("nil"); - } - } - - @CoreMethod(names = "nil?", needsSelf = false, maxArgs = 0) - public abstract static class NilNode extends CoreMethodNode { - - public NilNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public NilNode(NilNode prev) { - super(prev); - } - - @Specialization - public boolean nil() { - return true; - } - } - - @CoreMethod(names = "to_i", needsSelf = false, maxArgs = 0) - public abstract static class ToINode extends CoreMethodNode { - - public ToINode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ToINode(ToINode prev) { - super(prev); - } - - @Specialization - public int toI() { - return 0; - } - } - - @CoreMethod(names = "to_s", needsSelf = false, maxArgs = 0) - public abstract static class ToSNode extends CoreMethodNode { - - public ToSNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ToSNode(ToSNode prev) { - super(prev); - } - - @Specialization - public RubyString toS() { - return getContext().makeString(""); - } - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ObjectNodes.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ObjectNodes.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,514 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.core; - -import java.math.*; -import java.util.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.core.array.*; -import com.oracle.truffle.ruby.runtime.methods.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -@CoreClass(name = "Object") -public abstract class ObjectNodes { - - @CoreMethod(names = "class", maxArgs = 0) - public abstract static class ClassNode extends CoreMethodNode { - - public ClassNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ClassNode(ClassNode prev) { - super(prev); - } - - @Specialization - public RubyClass getClass(boolean value) { - if (value) { - return getContext().getCoreLibrary().getTrueClass(); - } else { - return getContext().getCoreLibrary().getFalseClass(); - } - } - - @Specialization - public RubyClass getClass(@SuppressWarnings("unused") int value) { - return getContext().getCoreLibrary().getFixnumClass(); - } - - @Specialization - public RubyClass getClass(@SuppressWarnings("unused") BigInteger value) { - return getContext().getCoreLibrary().getBignumClass(); - } - - @Specialization - public RubyClass getClass(@SuppressWarnings("unused") double value) { - return getContext().getCoreLibrary().getFloatClass(); - } - - @Specialization - public RubyClass getClass(RubyBasicObject self) { - return self.getRubyClass(); - } - - } - - @CoreMethod(names = "dup", maxArgs = 0) - public abstract static class DupNode extends CoreMethodNode { - - public DupNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public DupNode(DupNode prev) { - super(prev); - } - - @Specialization - public Object dup(RubyObject self) { - return self.dup(); - } - - } - - @CoreMethod(names = "extend", isSplatted = true, minArgs = 1) - public abstract static class ExtendNode extends CoreMethodNode { - - public ExtendNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ExtendNode(ExtendNode prev) { - super(prev); - } - - @Specialization - public RubyBasicObject extend(RubyBasicObject self, Object[] args) { - for (int n = 0; n < args.length; n++) { - self.extend((RubyModule) args[n]); - } - - return self; - } - - } - - @CoreMethod(names = "freeze", maxArgs = 0) - public abstract static class FreezeNode extends CoreMethodNode { - - public FreezeNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public FreezeNode(FreezeNode prev) { - super(prev); - } - - @Specialization - public RubyObject freeze(RubyObject self) { - self.frozen = true; - return self; - } - - } - - @CoreMethod(names = "frozen?", maxArgs = 0) - public abstract static class FrozenNode extends CoreMethodNode { - - public FrozenNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public FrozenNode(FrozenNode prev) { - super(prev); - } - - @Specialization - public boolean isFrozen(RubyObject self) { - return self.frozen; - } - - } - - @CoreMethod(names = "inspect", maxArgs = 0) - public abstract static class InspectNode extends CoreMethodNode { - - public InspectNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public InspectNode(InspectNode prev) { - super(prev); - } - - @Specialization - public RubyString inspect(boolean value) { - return getContext().makeString(Boolean.toString(value)); - } - - @Specialization - public RubyString inspect(int value) { - return getContext().makeString(Integer.toString(value)); - } - - @Specialization - public RubyString inspect(BigInteger value) { - return getContext().makeString(value.toString()); - } - - @Specialization - public RubyString inspect(double value) { - return getContext().makeString(Double.toString(value)); - } - - @Specialization - public RubyString inspect(RubyObject self) { - return getContext().makeString(self.inspect()); - } - - } - - @CoreMethod(names = "instance_eval", needsBlock = true, maxArgs = 0) - public abstract static class InstanceEvalNode extends CoreMethodNode { - - public InstanceEvalNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public InstanceEvalNode(InstanceEvalNode prev) { - super(prev); - } - - @Specialization - public Object instanceEval(VirtualFrame frame, RubyObject self, RubyProc block) { - return block.callWithModifiedSelf(frame.pack(), self); - } - - } - - @CoreMethod(names = "instance_variable_defined?", minArgs = 1, maxArgs = 1) - public abstract static class InstanceVariableDefinedNode extends CoreMethodNode { - - public InstanceVariableDefinedNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public InstanceVariableDefinedNode(InstanceVariableDefinedNode prev) { - super(prev); - } - - @Specialization - public boolean isInstanceVariableDefined(RubyBasicObject object, RubyString name) { - return object.isInstanceVariableDefined(RubyObject.checkInstanceVariableName(getContext(), name.toString())); - } - - @Specialization - public boolean isInstanceVariableDefined(RubyBasicObject object, RubySymbol name) { - return object.isInstanceVariableDefined(RubyObject.checkInstanceVariableName(getContext(), name.toString())); - } - - } - - @CoreMethod(names = "instance_variable_get", minArgs = 1, maxArgs = 1) - public abstract static class InstanceVariableGetNode extends CoreMethodNode { - - public InstanceVariableGetNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public InstanceVariableGetNode(InstanceVariableGetNode prev) { - super(prev); - } - - @Specialization - public Object isInstanceVariableGet(RubyBasicObject object, RubyString name) { - return object.getInstanceVariable(RubyObject.checkInstanceVariableName(getContext(), name.toString())); - } - - @Specialization - public Object isInstanceVariableGet(RubyBasicObject object, RubySymbol name) { - return object.getInstanceVariable(RubyObject.checkInstanceVariableName(getContext(), name.toString())); - } - - } - - @CoreMethod(names = "instance_variable_set", minArgs = 2, maxArgs = 2) - public abstract static class InstanceVariableSetNode extends CoreMethodNode { - - public InstanceVariableSetNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public InstanceVariableSetNode(InstanceVariableSetNode prev) { - super(prev); - } - - @Specialization - public Object isInstanceVariableSet(RubyBasicObject object, RubyString name, Object value) { - object.setInstanceVariable(RubyObject.checkInstanceVariableName(getContext(), name.toString()), value); - return value; - } - - @Specialization - public Object isInstanceVariableSet(RubyBasicObject object, RubySymbol name, Object value) { - object.setInstanceVariable(RubyObject.checkInstanceVariableName(getContext(), name.toString()), value); - return value; - } - - } - - @CoreMethod(names = "instance_variables", maxArgs = 0) - public abstract static class InstanceVariablesNode extends CoreMethodNode { - - public InstanceVariablesNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public InstanceVariablesNode(InstanceVariablesNode prev) { - super(prev); - } - - @Specialization - public RubyArray instanceVariables(RubyObject self) { - final String[] instanceVariableNames = self.getInstanceVariableNames(); - - Arrays.sort(instanceVariableNames); - - final RubyArray array = new RubyArray(getContext().getCoreLibrary().getArrayClass()); - - for (String name : instanceVariableNames) { - array.push(new RubyString(getContext().getCoreLibrary().getStringClass(), name)); - } - - return array; - } - - } - - @CoreMethod(names = {"is_a?", "instance_of?", "kind_of?"}, minArgs = 1, maxArgs = 1) - public abstract static class IsANode extends CoreMethodNode { - - public IsANode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public IsANode(IsANode prev) { - super(prev); - } - - @Specialization - public boolean isA(@SuppressWarnings("unused") RubyObject self, @SuppressWarnings("unused") NilPlaceholder nil) { - return false; - } - - @Specialization - public boolean isA(RubyObject self, RubyClass rubyClass) { - return self.getRubyClass().assignableTo(rubyClass); - } - - } - - @CoreMethod(names = "methods", minArgs = 0, maxArgs = 1) - public abstract static class MethodsNode extends CoreMethodNode { - - public MethodsNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public MethodsNode(MethodsNode prev) { - super(prev); - } - - @Specialization - public RubyArray methods(RubyObject self, boolean includeInherited) { - if (!includeInherited) { - self.getRubyClass().getContext().implementationMessage("Object#methods always returns inherited methods at the moment"); - } - - return methods(self, UndefinedPlaceholder.INSTANCE); - } - - @Specialization - public RubyArray methods(RubyObject self, @SuppressWarnings("unused") UndefinedPlaceholder includeInherited) { - final RubyArray array = new RubyArray(self.getRubyClass().getContext().getCoreLibrary().getArrayClass()); - - final Map methods = new HashMap<>(); - - self.getLookupNode().getMethods(methods); - - for (RubyMethod method : methods.values()) { - if (method.getVisibility() == Visibility.PUBLIC || method.getVisibility() == Visibility.PROTECTED) { - array.push(new RubySymbol(self.getRubyClass().getContext().getCoreLibrary().getSymbolClass(), method.getName())); - } - } - - return array; - } - - } - - @CoreMethod(names = "nil?", needsSelf = false, maxArgs = 0) - public abstract static class NilNode extends CoreMethodNode { - - public NilNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public NilNode(NilNode prev) { - super(prev); - } - - @Specialization - public boolean nil() { - return false; - } - } - - @CoreMethod(names = "object_id", needsSelf = true, maxArgs = 0) - public abstract static class ObjectIDNode extends CoreMethodNode { - - public ObjectIDNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ObjectIDNode(ObjectIDNode prev) { - super(prev); - } - - @Specialization - public Object objectID(RubyBasicObject object) { - return GeneralConversions.fixnumOrBignum(object.getObjectID()); - } - - } - - @CoreMethod(names = "respond_to?", minArgs = 1, maxArgs = 2) - public abstract static class RespondToNode extends CoreMethodNode { - - public RespondToNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public RespondToNode(RespondToNode prev) { - super(prev); - } - - @Specialization(order = 1) - public boolean doesRespondTo(Object object, RubyString name, @SuppressWarnings("unused") UndefinedPlaceholder checkVisibility) { - return doesRespondTo(getContext().getCoreLibrary().box(object), name.toString(), false); - } - - @Specialization(order = 2) - public boolean doesRespondTo(Object object, RubyString name, boolean dontCheckVisibility) { - return doesRespondTo(getContext().getCoreLibrary().box(object), name.toString(), dontCheckVisibility); - } - - @Specialization(order = 3) - public boolean doesRespondTo(Object object, RubySymbol name, @SuppressWarnings("unused") UndefinedPlaceholder checkVisibility) { - return doesRespondTo(getContext().getCoreLibrary().box(object), name.toString(), false); - } - - @Specialization(order = 4) - public boolean doesRespondTo(Object object, RubySymbol name, boolean dontCheckVisibility) { - return doesRespondTo(getContext().getCoreLibrary().box(object), name.toString(), dontCheckVisibility); - } - - private static boolean doesRespondTo(RubyBasicObject object, String name, boolean dontCheckVisibility) { - final RubyMethod method = object.getLookupNode().lookupMethod(name); - - if (method == null || method.isUndefined()) { - return false; - } - - if (dontCheckVisibility) { - return true; - } else { - return method.getVisibility() == Visibility.PUBLIC; - } - } - - } - - @CoreMethod(names = "singleton_class", maxArgs = 0) - public abstract static class SingletonClassNode extends CoreMethodNode { - - public SingletonClassNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public SingletonClassNode(SingletonClassNode prev) { - super(prev); - } - - @Specialization - public RubyClass singletonClass(RubyBasicObject self) { - return self.getSingletonClass(); - } - - } - - @CoreMethod(names = "singleton_methods", minArgs = 0, maxArgs = 1) - public abstract static class SingletonMethodsNode extends CoreMethodNode { - - public SingletonMethodsNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public SingletonMethodsNode(SingletonMethodsNode prev) { - super(prev); - } - - @Specialization - public RubyArray singletonMethods(RubyObject self, boolean includeInherited) { - if (!includeInherited) { - self.getRubyClass().getContext().implementationMessage("Object#singleton_methods always returns inherited methods at the moment"); - } - - return singletonMethods(self, UndefinedPlaceholder.INSTANCE); - } - - @Specialization - public RubyArray singletonMethods(RubyObject self, @SuppressWarnings("unused") UndefinedPlaceholder includeInherited) { - final RubyArray array = new RubyArray(self.getRubyClass().getContext().getCoreLibrary().getArrayClass()); - - for (RubyMethod method : self.getSingletonClass().getDeclaredMethods()) { - array.push(new RubySymbol(self.getRubyClass().getContext().getCoreLibrary().getSymbolClass(), method.getName())); - } - - return array; - } - - } - - @CoreMethod(names = "to_s", maxArgs = 0) - public abstract static class ToSNode extends CoreMethodNode { - - public ToSNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ToSNode(ToSNode prev) { - super(prev); - } - - @Specialization - public RubyString toS(RubyObject self) { - return getContext().makeString(self.toString()); - } - - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ObjectSpaceNodes.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ObjectSpaceNodes.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,151 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.core; - -import java.math.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -@CoreClass(name = "ObjectSpace") -public abstract class ObjectSpaceNodes { - - @CoreMethod(names = "_id2ref", isModuleMethod = true, needsSelf = false, minArgs = 1, maxArgs = 1) - public abstract static class ID2RefNode extends CoreMethodNode { - - public ID2RefNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ID2RefNode(ID2RefNode prev) { - super(prev); - } - - @Specialization - public Object id2Ref(int id) { - final Object object = getContext().getObjectSpaceManager().lookupId(id); - - if (object == null) { - return NilPlaceholder.INSTANCE; - } else { - return object; - } - } - - @Specialization - public Object id2Ref(BigInteger id) { - final Object object = getContext().getObjectSpaceManager().lookupId(id.longValue()); - - if (object == null) { - return NilPlaceholder.INSTANCE; - } else { - return object; - } - } - - } - - @CoreMethod(names = "each_object", isModuleMethod = true, needsSelf = false, needsBlock = true, minArgs = 0, maxArgs = 1) - public abstract static class EachObjectNode extends YieldingCoreMethodNode { - - public EachObjectNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public EachObjectNode(EachObjectNode prev) { - super(prev); - } - - @Specialization - public NilPlaceholder eachObject(VirtualFrame frame, @SuppressWarnings("unused") UndefinedPlaceholder ofClass, RubyProc block) { - for (RubyBasicObject object : getContext().getObjectSpaceManager().getObjects()) { - yield(frame, block, object); - } - return NilPlaceholder.INSTANCE; - } - - @Specialization - public NilPlaceholder eachObject(VirtualFrame frame, RubyClass ofClass, RubyProc block) { - for (RubyBasicObject object : getContext().getObjectSpaceManager().getObjects()) { - if (object.getRubyClass().assignableTo(ofClass)) { - yield(frame, block, object); - } - } - return NilPlaceholder.INSTANCE; - } - - } - - @CoreMethod(names = "define_finalizer", isModuleMethod = true, needsSelf = false, minArgs = 2, maxArgs = 2) - public abstract static class DefineFinalizerNode extends CoreMethodNode { - - public DefineFinalizerNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public DefineFinalizerNode(DefineFinalizerNode prev) { - super(prev); - } - - @Specialization - public RubyProc defineFinalizer(Object object, RubyProc finalizer) { - getContext().getObjectSpaceManager().defineFinalizer((RubyBasicObject) object, finalizer); - return finalizer; - } - } - - @CoreMethod(names = {"garbage_collect", "start"}, isModuleMethod = true, needsSelf = false, maxArgs = 0) - public abstract static class GarbageCollectNode extends CoreMethodNode { - - public GarbageCollectNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public GarbageCollectNode(GarbageCollectNode prev) { - super(prev); - } - - @Specialization - public NilPlaceholder garbageCollect() { - final RubyThread runningThread = getContext().getThreadManager().leaveGlobalLock(); - - try { - System.gc(); - } finally { - getContext().getThreadManager().enterGlobalLock(runningThread); - } - - return NilPlaceholder.INSTANCE; - } - } - - @CoreMethod(names = "undefine_finalizer", isModuleMethod = true, needsSelf = false, minArgs = 1, maxArgs = 1) - public abstract static class UndefineFinalizerNode extends CoreMethodNode { - - public UndefineFinalizerNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public UndefineFinalizerNode(UndefineFinalizerNode prev) { - super(prev); - } - - @Specialization - public Object undefineFinalizer(Object object) { - getContext().getObjectSpaceManager().undefineFinalizer((RubyBasicObject) object); - return object; - } - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ProcNodes.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ProcNodes.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.core; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; - -@CoreClass(name = "Proc") -public abstract class ProcNodes { - - @CoreMethod(names = {"call", "[]"}, isSplatted = true) - public abstract static class CallNode extends CoreMethodNode { - - public CallNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public CallNode(CallNode prev) { - super(prev); - } - - @Specialization - public Object call(VirtualFrame frame, RubyProc proc, Object[] args) { - return proc.call(frame.getCaller(), args); - } - - } - - @CoreMethod(names = "initialize", needsBlock = true, maxArgs = 0) - public abstract static class InitializeNode extends CoreMethodNode { - - public InitializeNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public InitializeNode(InitializeNode prev) { - super(prev); - } - - @Specialization - public NilPlaceholder initialize(VirtualFrame frame, RubyProc proc, RubyProc block) { - final RubyArguments callerArguments = frame.getCaller().unpack().getArguments(RubyArguments.class); - proc.initialize(RubyProc.Type.PROC, callerArguments.getSelf(), callerArguments.getBlock(), block.getMethod()); - return NilPlaceholder.INSTANCE; - } - - } - - @CoreMethod(names = "lambda?", maxArgs = 0) - public abstract static class LambdaNode extends CoreMethodNode { - - public LambdaNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public LambdaNode(LambdaNode prev) { - super(prev); - } - - @Specialization - public boolean lambda(RubyProc proc) { - return proc.getType() == RubyProc.Type.LAMBDA; - } - - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ProcessNodes.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ProcessNodes.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.core; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.ruby.runtime.*; - -@CoreClass(name = "Process") -public abstract class ProcessNodes { - - @CoreMethod(names = "pid", isModuleMethod = true, needsSelf = false, maxArgs = 0) - public abstract static class PidNode extends CoreMethodNode { - - public PidNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public PidNode(PidNode prev) { - super(prev); - } - - @Specialization - public int pid() { - return getContext().getPOSIX().getpid(); - } - - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/RangeNodes.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/RangeNodes.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,275 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.core; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.utilities.*; -import com.oracle.truffle.ruby.nodes.call.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.control.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.core.array.*; -import com.oracle.truffle.ruby.runtime.core.range.*; - -@CoreClass(name = "Range") -public abstract class RangeNodes { - - @CoreMethod(names = {"collect", "map"}, needsBlock = true, maxArgs = 0) - public abstract static class CollectNode extends YieldingCoreMethodNode { - - public CollectNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public CollectNode(CollectNode prev) { - super(prev); - } - - @Specialization - public RubyArray collect(VirtualFrame frame, FixnumRange range, RubyProc block) { - final RubyContext context = getContext(); - - final RubyArray array = new RubyArray(context.getCoreLibrary().getArrayClass()); - - for (int n = range.getBegin(); n < range.getExclusiveEnd(); n++) { - array.push(yield(frame, block, n)); - } - - return array; - } - - } - - @CoreMethod(names = "each", needsBlock = true, maxArgs = 0) - public abstract static class EachNode extends YieldingCoreMethodNode { - - private final BranchProfile breakProfile = new BranchProfile(); - private final BranchProfile nextProfile = new BranchProfile(); - private final BranchProfile redoProfile = new BranchProfile(); - - public EachNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public EachNode(EachNode prev) { - super(prev); - } - - @Specialization - public Object each(VirtualFrame frame, FixnumRange range, RubyProc block) { - outer: for (int n = range.getBegin(); n < range.getExclusiveEnd(); n++) { - while (true) { - try { - yield(frame, block, n); - continue outer; - } catch (BreakException e) { - breakProfile.enter(); - return e.getResult(); - } catch (NextException e) { - nextProfile.enter(); - continue outer; - } catch (RedoException e) { - redoProfile.enter(); - } - } - } - - return range; - } - - } - - @CoreMethod(names = "exclude_end?", maxArgs = 0) - public abstract static class ExcludeEndNode extends CoreMethodNode { - - public ExcludeEndNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ExcludeEndNode(ExcludeEndNode prev) { - super(prev); - } - - @Specialization - public boolean excludeEnd(RubyRange range) { - return range.doesExcludeEnd(); - } - - } - - @CoreMethod(names = "first", maxArgs = 0) - public abstract static class FirstNode extends CoreMethodNode { - - public FirstNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public FirstNode(FirstNode prev) { - super(prev); - } - - @Specialization - public int each(FixnumRange range) { - return range.getBegin(); - } - - @Specialization - public Object each(ObjectRange range) { - return range.getBegin(); - } - - } - - @CoreMethod(names = "include?", maxArgs = 1) - public abstract static class IncludeNode extends CoreMethodNode { - - @Child protected DispatchHeadNode callLess; - @Child protected DispatchHeadNode callGreater; - @Child protected DispatchHeadNode callGreaterEqual; - - public IncludeNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - callLess = adoptChild(new DispatchHeadNode(context, getSourceSection(), "<", false)); - callGreater = adoptChild(new DispatchHeadNode(context, getSourceSection(), ">", false)); - callGreaterEqual = adoptChild(new DispatchHeadNode(context, getSourceSection(), ">=", false)); - } - - public IncludeNode(IncludeNode prev) { - super(prev); - callLess = adoptChild(prev.callLess); - callGreater = adoptChild(prev.callGreater); - callGreaterEqual = adoptChild(prev.callGreaterEqual); - } - - @Specialization - public boolean include(FixnumRange range, int value) { - return value >= range.getBegin() && value < range.getExclusiveEnd(); - } - - @Specialization - public boolean include(VirtualFrame frame, ObjectRange range, Object value) { - if ((boolean) callLess.dispatch(frame, value, null, range.getBegin())) { - return false; - } - - if (range.doesExcludeEnd()) { - if ((boolean) callGreaterEqual.dispatch(frame, value, null, range.getEnd())) { - return false; - } - } else { - if ((boolean) callGreater.dispatch(frame, value, null, range.getEnd())) { - return false; - } - } - - return true; - } - } - - @CoreMethod(names = "last", maxArgs = 0) - public abstract static class LastNode extends CoreMethodNode { - - public LastNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public LastNode(LastNode prev) { - super(prev); - } - - @Specialization - public int last(FixnumRange range) { - return range.getEnd(); - } - - @Specialization - public Object last(ObjectRange range) { - return range.getEnd(); - } - - } - - @CoreMethod(names = "step", needsBlock = true, minArgs = 1, maxArgs = 1) - public abstract static class StepNode extends YieldingCoreMethodNode { - - private final BranchProfile breakProfile = new BranchProfile(); - private final BranchProfile nextProfile = new BranchProfile(); - private final BranchProfile redoProfile = new BranchProfile(); - - public StepNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public StepNode(StepNode prev) { - super(prev); - } - - @Specialization - public Object step(VirtualFrame frame, FixnumRange range, int step, RubyProc block) { - outer: for (int n = range.getBegin(); n < range.getExclusiveEnd(); n += step) { - while (true) { - try { - yield(frame, block, n); - continue outer; - } catch (BreakException e) { - breakProfile.enter(); - return e.getResult(); - } catch (NextException e) { - nextProfile.enter(); - continue outer; - } catch (RedoException e) { - redoProfile.enter(); - } - } - } - - return range; - } - - } - - @CoreMethod(names = "to_a", maxArgs = 0) - public abstract static class ToANode extends CoreMethodNode { - - public ToANode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ToANode(ToANode prev) { - super(prev); - } - - @Specialization - public RubyArray toA(RubyRange range) { - return range.toArray(); - } - - } - - @CoreMethod(names = "to_s", maxArgs = 0) - public abstract static class ToSNode extends CoreMethodNode { - - public ToSNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ToSNode(ToSNode prev) { - super(prev); - } - - @Specialization - public RubyString toS(RubyRange range) { - return getContext().makeString(range.toString()); - } - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/RegexpNodes.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/RegexpNodes.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,114 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.core; - -import java.util.regex.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; - -@CoreClass(name = "Regexp") -public abstract class RegexpNodes { - - @CoreMethod(names = {"=~", "==="}, minArgs = 1, maxArgs = 1) - public abstract static class MatchOperatorNode extends CoreMethodNode { - - public MatchOperatorNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public MatchOperatorNode(MatchOperatorNode prev) { - super(prev); - } - - @Specialization - public Object match(VirtualFrame frame, RubyRegexp regexp, RubyString string) { - return regexp.matchOperator(frame.getCaller().unpack(), string.toString()); - } - - } - - @CoreMethod(names = "!~", minArgs = 1, maxArgs = 1) - public abstract static class NotMatchOperatorNode extends CoreMethodNode { - - public NotMatchOperatorNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public NotMatchOperatorNode(NotMatchOperatorNode prev) { - super(prev); - } - - @Specialization - public Object match(VirtualFrame frame, RubyRegexp regexp, RubyString string) { - return regexp.matchOperator(frame.getCaller().unpack(), string.toString()) == NilPlaceholder.INSTANCE; - } - - } - - @CoreMethod(names = "escape", isModuleMethod = true, needsSelf = false, minArgs = 1, maxArgs = 1) - public abstract static class EscapeNode extends CoreMethodNode { - - public EscapeNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public EscapeNode(EscapeNode prev) { - super(prev); - } - - @Specialization - public RubyString sqrt(RubyString pattern) { - return getContext().makeString(Pattern.quote(pattern.toString())); - } - - } - - @CoreMethod(names = "initialize", minArgs = 1, maxArgs = 1) - public abstract static class InitializeNode extends CoreMethodNode { - - public InitializeNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public InitializeNode(InitializeNode prev) { - super(prev); - } - - @Specialization - public NilPlaceholder initialize(RubyRegexp regexp, RubyString string) { - regexp.initialize(string.toString()); - return NilPlaceholder.INSTANCE; - } - - } - - @CoreMethod(names = "match", minArgs = 1, maxArgs = 1) - public abstract static class MatchNode extends CoreMethodNode { - - public MatchNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public MatchNode(MatchNode prev) { - super(prev); - } - - @Specialization - public Object match(RubyRegexp regexp, RubyString string) { - return regexp.match(string.toString()); - } - - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/SignalNodes.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/SignalNodes.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.core; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.ruby.runtime.*; - -@CoreClass(name = "Signal") -public abstract class SignalNodes { - - @CoreMethod(names = "trap", isModuleMethod = true, needsSelf = false, minArgs = 1, maxArgs = 1) - public abstract static class SignalNode extends CoreMethodNode { - - public SignalNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public SignalNode(SignalNode prev) { - super(prev); - } - - @Specialization - public NilPlaceholder trap(@SuppressWarnings("unused") Object signal) { - getContext().implementationMessage("Signal#trap doesn't do anything"); - return NilPlaceholder.INSTANCE; - } - - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/StringNodes.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/StringNodes.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,559 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.core; - -import java.util.*; -import java.util.regex.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.core.array.*; - -@CoreClass(name = "String") -public abstract class StringNodes { - - @CoreMethod(names = "+", minArgs = 1, maxArgs = 1) - public abstract static class AddNode extends CoreMethodNode { - - public AddNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public AddNode(AddNode prev) { - super(prev); - } - - @Specialization - public RubyString add(RubyString a, RubyString b) { - return new RubyString(a.getRubyClass().getContext().getCoreLibrary().getStringClass(), a.toString() + b.toString()); - } - } - - @CoreMethod(names = {"==", "==="}, minArgs = 1, maxArgs = 1) - public abstract static class EqualNode extends CoreMethodNode { - - public EqualNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public EqualNode(EqualNode prev) { - super(prev); - } - - @Specialization - public boolean equal(@SuppressWarnings("unused") RubyString a, @SuppressWarnings("unused") NilPlaceholder b) { - return false; - } - - @Specialization - public boolean equal(RubyString a, RubyString b) { - return a.toString().equals(b.toString()); - } - } - - @CoreMethod(names = "!=", minArgs = 1, maxArgs = 1) - public abstract static class NotEqualNode extends CoreMethodNode { - - public NotEqualNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public NotEqualNode(NotEqualNode prev) { - super(prev); - } - - @Specialization - public boolean equal(@SuppressWarnings("unused") RubyString a, @SuppressWarnings("unused") NilPlaceholder b) { - return true; - } - - @Specialization - public boolean notEqual(RubyString a, RubyString b) { - return !a.toString().equals(b.toString()); - } - - } - - @CoreMethod(names = "<=>", minArgs = 1, maxArgs = 1) - public abstract static class CompareNode extends CoreMethodNode { - - public CompareNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public CompareNode(CompareNode prev) { - super(prev); - } - - @Specialization - public int compare(RubyString a, RubyString b) { - return a.toString().compareTo(b.toString()); - } - } - - @CoreMethod(names = "<<", minArgs = 1, maxArgs = 1) - public abstract static class ConcatNode extends CoreMethodNode { - - public ConcatNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ConcatNode(ConcatNode prev) { - super(prev); - } - - @Specialization - public RubyString concat(RubyString string, RubyString other) { - string.replace(string.toString() + other.toString()); - return string; - } - } - - @CoreMethod(names = "%", minArgs = 1, maxArgs = 1, isSplatted = true) - public abstract static class FormatNode extends CoreMethodNode { - - public FormatNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public FormatNode(FormatNode prev) { - super(prev); - } - - @Specialization - public RubyString format(RubyString format, Object[] args) { - final RubyContext context = getContext(); - - if (args.length == 1 && args[0] instanceof RubyArray) { - return context.makeString(StringFormatter.format(format.toString(), ((RubyArray) args[0]).asList())); - } else { - return context.makeString(StringFormatter.format(format.toString(), Arrays.asList(args))); - } - } - } - - @CoreMethod(names = "[]", minArgs = 1, maxArgs = 2, isSplatted = true) - public abstract static class GetIndexNode extends CoreMethodNode { - - public GetIndexNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public GetIndexNode(GetIndexNode prev) { - super(prev); - } - - @Specialization - public Object getIndex(RubyString string, Object[] args) { - return RubyString.getIndex(getContext(), string.toString(), args); - } - } - - @CoreMethod(names = "=~", minArgs = 1, maxArgs = 1) - public abstract static class MatchOperatorNode extends CoreMethodNode { - - public MatchOperatorNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public MatchOperatorNode(MatchOperatorNode prev) { - super(prev); - } - - @Specialization - public Object match(VirtualFrame frame, RubyString string, RubyRegexp regexp) { - return regexp.matchOperator(frame, string.toString()); - } - } - - @CoreMethod(names = "chomp", maxArgs = 0) - public abstract static class ChompNode extends CoreMethodNode { - - public ChompNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ChompNode(ChompNode prev) { - super(prev); - } - - @Specialization - public RubyString chomp(RubyString string) { - return string.getRubyClass().getContext().makeString(string.toString().trim()); - } - } - - @CoreMethod(names = "chomp!", maxArgs = 0) - public abstract static class ChompBangNode extends CoreMethodNode { - - public ChompBangNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ChompBangNode(ChompBangNode prev) { - super(prev); - } - - @Specialization - public RubyString chompBang(RubyString string) { - string.replace(string.toString().trim()); - return string; - } - } - - @CoreMethod(names = "downcase", maxArgs = 0) - public abstract static class DowncaseNode extends CoreMethodNode { - - public DowncaseNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public DowncaseNode(DowncaseNode prev) { - super(prev); - } - - @Specialization - public RubyString downcase(RubyString string) { - return string.getRubyClass().getContext().makeString(string.toString().toLowerCase()); - } - } - - @CoreMethod(names = "downcase!", maxArgs = 0) - public abstract static class DowncaseBangNode extends CoreMethodNode { - - public DowncaseBangNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public DowncaseBangNode(DowncaseBangNode prev) { - super(prev); - } - - @Specialization - public RubyString downcase(RubyString string) { - string.replace(string.toString().toLowerCase()); - return string; - } - } - - @CoreMethod(names = "empty?", maxArgs = 0) - public abstract static class EmptyNode extends CoreMethodNode { - - public EmptyNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public EmptyNode(EmptyNode prev) { - super(prev); - } - - @Specialization - public boolean empty(RubyString string) { - return string.toString().isEmpty(); - } - } - - @CoreMethod(names = "end_with?", minArgs = 1, maxArgs = 1) - public abstract static class EndWithNode extends CoreMethodNode { - - public EndWithNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public EndWithNode(EndWithNode prev) { - super(prev); - } - - @Specialization - public boolean endWith(RubyString string, RubyString b) { - return string.toString().endsWith(b.toString()); - } - } - - @CoreMethod(names = "gsub", minArgs = 2, maxArgs = 2) - public abstract static class GsubNode extends CoreMethodNode { - - public GsubNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public GsubNode(GsubNode prev) { - super(prev); - } - - @Specialization - public RubyString gsub(RubyString string, RubyString regexpString, RubyString replacement) { - final RubyRegexp regexp = new RubyRegexp(getContext().getCoreLibrary().getRegexpClass(), regexpString.toString()); - return gsub(string, regexp, replacement); - } - - @Specialization - public RubyString gsub(RubyString string, RubyRegexp regexp, RubyString replacement) { - return getContext().makeString(regexp.getPattern().matcher(string.toString()).replaceAll(replacement.toString())); - } - } - - @CoreMethod(names = "inspect", maxArgs = 0) - public abstract static class InspectNode extends CoreMethodNode { - - public InspectNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public InspectNode(InspectNode prev) { - super(prev); - } - - @Specialization - public RubyString inspect(RubyString string) { - return getContext().makeString("\"" + string.toString().replace("\\", "\\\\").replace("\"", "\\\"") + "\""); - } - } - - @CoreMethod(names = "ljust", minArgs = 1, maxArgs = 2) - public abstract static class LjustNode extends CoreMethodNode { - - public LjustNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public LjustNode(LjustNode prev) { - super(prev); - } - - @Specialization - public RubyString ljust(RubyString string, int length, @SuppressWarnings("unused") UndefinedPlaceholder padding) { - return getContext().makeString(RubyString.ljust(string.toString(), length, " ")); - } - - @Specialization - public RubyString ljust(RubyString string, int length, RubyString padding) { - return getContext().makeString(RubyString.ljust(string.toString(), length, padding.toString())); - } - - } - - @CoreMethod(names = "size", maxArgs = 0) - public abstract static class SizeNode extends CoreMethodNode { - - public SizeNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public SizeNode(SizeNode prev) { - super(prev); - } - - @Specialization - public int size(RubyString string) { - return string.toString().length(); - } - } - - @CoreMethod(names = "match", minArgs = 1, maxArgs = 1) - public abstract static class MatchNode extends CoreMethodNode { - - public MatchNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public MatchNode(MatchNode prev) { - super(prev); - } - - @Specialization - public Object match(RubyString string, RubyString regexpString) { - final RubyRegexp regexp = new RubyRegexp(getContext().getCoreLibrary().getRegexpClass(), regexpString.toString()); - return regexp.match(string.toString()); - } - - @Specialization - public Object match(RubyString string, RubyRegexp regexp) { - return regexp.match(string.toString()); - } - } - - @CoreMethod(names = "rjust", minArgs = 1, maxArgs = 2) - public abstract static class RjustNode extends CoreMethodNode { - - public RjustNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public RjustNode(RjustNode prev) { - super(prev); - } - - @Specialization - public RubyString rjust(RubyString string, int length, @SuppressWarnings("unused") UndefinedPlaceholder padding) { - return getContext().makeString(RubyString.rjust(string.toString(), length, " ")); - } - - @Specialization - public RubyString rjust(RubyString string, int length, RubyString padding) { - return getContext().makeString(RubyString.rjust(string.toString(), length, padding.toString())); - } - - } - - @CoreMethod(names = "scan", minArgs = 1, maxArgs = 1) - public abstract static class ScanNode extends CoreMethodNode { - - public ScanNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ScanNode(ScanNode prev) { - super(prev); - } - - @Specialization - public RubyArray scan(RubyString string, RubyString regexp) { - return RubyString.scan(getContext(), string.toString(), Pattern.compile(regexp.toString())); - } - - @Specialization - public RubyArray scan(RubyString string, RubyRegexp regexp) { - return RubyString.scan(getContext(), string.toString(), regexp.getPattern()); - } - - } - - @CoreMethod(names = "split", minArgs = 1, maxArgs = 1) - public abstract static class SplitNode extends CoreMethodNode { - - public SplitNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public SplitNode(SplitNode prev) { - super(prev); - } - - @Specialization - public RubyArray split(RubyString string, RubyString sep) { - final RubyContext context = getContext(); - - final String[] components = string.toString().split(Pattern.quote(sep.toString())); - - final Object[] objects = new Object[components.length]; - - for (int n = 0; n < objects.length; n++) { - objects[n] = context.makeString(components[n]); - } - - return RubyArray.specializedFromObjects(context.getCoreLibrary().getArrayClass(), objects); - } - - @Specialization - public RubyArray split(RubyString string, RubyRegexp sep) { - final RubyContext context = getContext(); - - final String[] components = string.toString().split(sep.getPattern().pattern()); - - final Object[] objects = new Object[components.length]; - - for (int n = 0; n < objects.length; n++) { - objects[n] = context.makeString(components[n]); - } - - return RubyArray.specializedFromObjects(context.getCoreLibrary().getArrayClass(), objects); - } - } - - @CoreMethod(names = "start_with?", minArgs = 1, maxArgs = 1) - public abstract static class StartWithNode extends CoreMethodNode { - - public StartWithNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public StartWithNode(StartWithNode prev) { - super(prev); - } - - @Specialization - public boolean endWith(RubyString string, RubyString b) { - return string.toString().startsWith(b.toString()); - } - } - - @CoreMethod(names = "to_f", maxArgs = 0) - public abstract static class ToFNode extends CoreMethodNode { - - public ToFNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ToFNode(ToFNode prev) { - super(prev); - } - - @Specialization - public double toF(RubyString string) { - return Double.parseDouble(string.toString()); - } - } - - @CoreMethod(names = "to_i", maxArgs = 0) - public abstract static class ToINode extends CoreMethodNode { - - public ToINode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ToINode(ToINode prev) { - super(prev); - } - - @Specialization - public Object toI(RubyString string) { - return string.toInteger(); - } - } - - @CoreMethod(names = "to_s", maxArgs = 0) - public abstract static class ToSNode extends CoreMethodNode { - - public ToSNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ToSNode(ToSNode prev) { - super(prev); - } - - @Specialization - public RubyString toF(RubyString string) { - return string; - } - } - - @CoreMethod(names = {"to_sym", "intern"}, maxArgs = 0) - public abstract static class ToSymNode extends CoreMethodNode { - - public ToSymNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ToSymNode(ToSymNode prev) { - super(prev); - } - - @Specialization - public RubySymbol toSym(RubyString string) { - return new RubySymbol(getContext().getCoreLibrary().getSymbolClass(), string.toString()); - } - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/StructNodes.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/StructNodes.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.core; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; - -@CoreClass(name = "Struct") -public abstract class StructNodes { - - @CoreMethod(names = "initialize", needsBlock = true, appendCallNode = true, isSplatted = true) - public abstract static class InitalizeNode extends CoreMethodNode { - - public InitalizeNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public InitalizeNode(InitalizeNode prev) { - super(prev); - } - - @Specialization - public NilPlaceholder initialize(VirtualFrame frame, RubyClass struct, Object[] args, Object block, Node callSite) { - CompilerDirectives.transferToInterpreter(); - - final RubySymbol[] symbols = new RubySymbol[args.length]; - - for (int n = 0; n < args.length; n++) { - symbols[n] = (RubySymbol) args[n]; - } - - for (RubySymbol symbol : symbols) { - ModuleNodes.AttrAccessorNode.attrAccessor(getContext(), callSite.getSourceSection(), struct, symbol.toString()); - } - - if (!RubyNilClass.isNil(block)) { - ((RubyProc) block).callWithModifiedSelf(frame.pack(), struct); - } - - return NilPlaceholder.INSTANCE; - } - - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/SymbolNodes.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/SymbolNodes.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.core; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; - -@CoreClass(name = "Symbol") -public abstract class SymbolNodes { - - @CoreMethod(names = {"==", "==="}, minArgs = 1, maxArgs = 1) - public abstract static class EqualNode extends CoreMethodNode { - - public EqualNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public EqualNode(EqualNode prev) { - super(prev); - } - - @Specialization - public boolean equal(@SuppressWarnings("unused") RubyString a, @SuppressWarnings("unused") NilPlaceholder b) { - return false; - } - - @Specialization - public boolean equal(RubySymbol a, RubySymbol b) { - return a.toString().equals(b.toString()); - } - - @Specialization - public boolean equal(RubySymbol a, RubyString b) { - return a.toString().equals(b.toString()); - } - - @Specialization - public boolean equal(RubySymbol a, int b) { - return a.toString().equals(Integer.toString(b)); - } - - } - - @CoreMethod(names = "empty?", maxArgs = 0) - public abstract static class EmptyNode extends CoreMethodNode { - - public EmptyNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public EmptyNode(EmptyNode prev) { - super(prev); - } - - @Specialization - public boolean empty(RubySymbol symbol) { - return symbol.toString().isEmpty(); - } - - } - - @CoreMethod(names = "to_proc", maxArgs = 0) - public abstract static class ToProcNode extends CoreMethodNode { - - public ToProcNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ToProcNode(ToProcNode prev) { - super(prev); - } - - @Specialization - public RubyProc toProc(RubySymbol symbol) { - // TODO(CS): this should be doing all kinds of caching - return symbol.toProc(); - } - } - - @CoreMethod(names = "to_sym", maxArgs = 0) - public abstract static class ToSymNode extends CoreMethodNode { - - public ToSymNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ToSymNode(ToSymNode prev) { - super(prev); - } - - @Specialization - public RubySymbol toSym(RubySymbol symbol) { - return symbol; - } - - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/SystemNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/SystemNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.core; - -import java.io.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; - -/** - * Represents an expression that is evaluated by running it as a system command via forking and - * execing, and then taking stdout as a string. - */ -@NodeInfo(shortName = "system") -public class SystemNode extends RubyNode { - - @Child protected RubyNode child; - - public SystemNode(RubyContext context, SourceSection sourceSection, RubyNode child) { - super(context, sourceSection); - this.child = adoptChild(child); - } - - @Override - public Object execute(VirtualFrame frame) { - final RubyContext context = getContext(); - - final String command = child.execute(frame).toString(); - - Process process; - - try { - // We need to run via bash to get the variable and other expansion we expect - process = Runtime.getRuntime().exec(new String[]{"bash", "-c", command}); - } catch (IOException e) { - throw new RuntimeException(e); - } - - final InputStream stdout = process.getInputStream(); - final BufferedReader reader = new BufferedReader(new InputStreamReader(stdout)); - - final StringBuilder resultBuilder = new StringBuilder(); - - String line; - - // TODO(cs): this isn't great for binary output - - try { - while ((line = reader.readLine()) != null) { - resultBuilder.append(line); - resultBuilder.append("\n"); - } - } catch (IOException e) { - throw new RuntimeException(e); - } - - return context.makeString(resultBuilder.toString()); - } -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ThreadNodes.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ThreadNodes.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.core; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; - -@CoreClass(name = "Thread") -public abstract class ThreadNodes { - - @CoreMethod(names = "initialize", needsBlock = true, maxArgs = 0) - public abstract static class InitializeNode extends CoreMethodNode { - - public InitializeNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public InitializeNode(InitializeNode prev) { - super(prev); - } - - @Specialization - public NilPlaceholder initialize(RubyThread thread, RubyProc block) { - thread.initialize(block); - return NilPlaceholder.INSTANCE; - } - - } - - @CoreMethod(names = "join", maxArgs = 0) - public abstract static class JoinNode extends CoreMethodNode { - - public JoinNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public JoinNode(JoinNode prev) { - super(prev); - } - - @Specialization - public RubyThread join(RubyThread self) { - self.join(); - return self; - } - - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/TimeNodes.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/TimeNodes.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.core; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; - -@CoreClass(name = "Time") -public abstract class TimeNodes { - - @CoreMethod(names = "-", minArgs = 1, maxArgs = 1) - public abstract static class SubNode extends CoreMethodNode { - - public SubNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public SubNode(SubNode prev) { - super(prev); - } - - @Specialization - public double sub(RubyTime a, RubyTime b) { - return a.subtract(b); - } - - } - - @CoreMethod(names = "now", isModuleMethod = true, needsSelf = false, maxArgs = 0) - public abstract static class NowNode extends CoreMethodNode { - - public NowNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public NowNode(NowNode prev) { - super(prev); - } - - @Specialization - public RubyTime now() { - return RubyTime.fromDate(getContext().getCoreLibrary().getTimeClass(), System.currentTimeMillis()); - } - - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/TrueClassNodes.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/TrueClassNodes.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,97 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.core; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; - -@CoreClass(name = "TrueClass") -public abstract class TrueClassNodes { - - @CoreMethod(names = "!", needsSelf = false, maxArgs = 0) - public abstract static class NotNode extends CoreMethodNode { - - public NotNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public NotNode(NotNode prev) { - super(prev); - } - - @Specialization - public boolean not() { - return false; - } - - } - - @CoreMethod(names = {"==", "===", "=~"}, needsSelf = false, minArgs = 1, maxArgs = 1) - public abstract static class EqualNode extends CoreMethodNode { - - public EqualNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public EqualNode(EqualNode prev) { - super(prev); - } - - @Specialization - public boolean equal(boolean other) { - return other; - } - - @Specialization - public boolean equal(Object other) { - return other instanceof Boolean && ((boolean) other); - } - - } - - @CoreMethod(names = "^", needsSelf = false, minArgs = 1, maxArgs = 1) - public abstract static class XorNode extends CoreMethodNode { - - public XorNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public XorNode(XorNode prev) { - super(prev); - } - - @Specialization - public boolean xor(boolean other) { - return true ^ other; - } - - } - - @CoreMethod(names = "to_s", needsSelf = false, maxArgs = 0) - public abstract static class ToSNode extends CoreMethodNode { - - public ToSNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ToSNode(ToSNode prev) { - super(prev); - } - - @Specialization - public RubyString toS() { - return getContext().makeString("true"); - } - - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/YieldingCoreMethodNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/YieldingCoreMethodNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.core; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.ruby.nodes.yield.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; - -public abstract class YieldingCoreMethodNode extends CoreMethodNode { - - @Child protected YieldDispatchNode dispatchNode; - - public YieldingCoreMethodNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - dispatchNode = adoptChild(new UninitializedYieldDispatchNode(context, getSourceSection())); - } - - public YieldingCoreMethodNode(YieldingCoreMethodNode prev) { - super(prev); - dispatchNode = adoptChild(prev.dispatchNode); - } - - public Object yield(VirtualFrame frame, RubyProc block, Object... arguments) { - return dispatchNode.dispatch(frame, block, arguments); - } - - public boolean yieldBoolean(VirtualFrame frame, RubyProc block, Object... arguments) { - return GeneralConversions.toBoolean(dispatchNode.dispatch(frame, block, arguments)); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/debug/ActiveEnterDebugProbe.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/debug/ActiveEnterDebugProbe.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.debug; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; - -public abstract class ActiveEnterDebugProbe extends RubyProbe { - - private final Assumption activeAssumption; - - private final InlinableMethodImplementation inlinable; - private final RubyRootNode inlinedRoot; - - public ActiveEnterDebugProbe(RubyContext context, Assumption activeAssumption, RubyProc proc) { - super(context, false); - this.activeAssumption = activeAssumption; - inlinable = ((InlinableMethodImplementation) proc.getMethod().getImplementation()); - inlinedRoot = inlinable.getCloneOfPristineRootNode(); - } - - @Override - public void enter(Node astNode, VirtualFrame frame) { - try { - activeAssumption.check(); - } catch (InvalidAssumptionException e) { - replace(createInactive()); - return; - } - - final RubyArguments arguments = new RubyArguments(inlinable.getDeclarationFrame(), NilPlaceholder.INSTANCE, null, 14); - final VirtualFrame inlinedFrame = Truffle.getRuntime().createVirtualFrame(frame.pack(), arguments, inlinable.getFrameDescriptor()); - inlinedRoot.execute(inlinedFrame); - } - - protected abstract InactiveEnterDebugProbe createInactive(); - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/debug/ActiveLeaveDebugProbe.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/debug/ActiveLeaveDebugProbe.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.debug; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; - -public abstract class ActiveLeaveDebugProbe extends RubyProbe { - - private final Assumption activeAssumption; - - private final InlinableMethodImplementation inlinable; - private final RubyRootNode inlinedRoot; - - public ActiveLeaveDebugProbe(RubyContext context, Assumption activeAssumption, RubyProc proc) { - super(context, false); - this.activeAssumption = activeAssumption; - inlinable = ((InlinableMethodImplementation) proc.getMethod().getImplementation()); - inlinedRoot = inlinable.getCloneOfPristineRootNode(); - } - - @Override - public void leave(Node astNode, VirtualFrame frame, Object result) { - try { - activeAssumption.check(); - } catch (InvalidAssumptionException e) { - replace(createInactive()); - return; - } - - final RubyArguments arguments = new RubyArguments(inlinable.getDeclarationFrame(), NilPlaceholder.INSTANCE, null, result); - final VirtualFrame inlinedFrame = Truffle.getRuntime().createVirtualFrame(frame.pack(), arguments, inlinable.getFrameDescriptor()); - inlinedRoot.execute(inlinedFrame); - } - - protected abstract InactiveLeaveDebugProbe createInactive(); - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/debug/ActiveLineDebugProbe.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/debug/ActiveLineDebugProbe.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.debug; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.debug.*; - -public class ActiveLineDebugProbe extends ActiveEnterDebugProbe { - - private final SourceLineLocation sourceLine; - - public ActiveLineDebugProbe(RubyContext context, SourceLineLocation sourceLine, Assumption activeAssumption, RubyProc proc) { - super(context, activeAssumption, proc); - this.sourceLine = sourceLine; - } - - @Override - protected InactiveEnterDebugProbe createInactive() { - final RubyContext rubyContext = (RubyContext) getContext(); - final RubyDebugManager manager = rubyContext.getRubyDebugManager(); - return new InactiveLineDebugProbe(rubyContext, sourceLine, manager.getAssumption(sourceLine)); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/debug/ActiveLocalDebugProbe.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/debug/ActiveLocalDebugProbe.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.debug; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.debug.*; - -public class ActiveLocalDebugProbe extends ActiveLeaveDebugProbe { - - private final MethodLocal methodLocal; - - public ActiveLocalDebugProbe(RubyContext context, MethodLocal methodLocal, Assumption activeAssumption, RubyProc proc) { - super(context, activeAssumption, proc); - this.methodLocal = methodLocal; - } - - @Override - protected InactiveLeaveDebugProbe createInactive() { - final RubyContext rubyContext = (RubyContext) getContext(); - final RubyDebugManager manager = rubyContext.getRubyDebugManager(); - return new InactiveLocalDebugProbe(rubyContext, methodLocal, manager.getAssumption(methodLocal)); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/debug/DebugNodes.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/debug/DebugNodes.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,184 +0,0 @@ -/* - * Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.debug; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.ruby.nodes.core.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.control.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.debug.*; -import com.oracle.truffle.ruby.runtime.methods.*; - -@CoreClass(name = "Debug") -public abstract class DebugNodes { - - @CoreMethod(names = "break", isModuleMethod = true, needsSelf = false, needsBlock = true, appendCallNode = true, minArgs = 0, maxArgs = 3) - public abstract static class BreakNode extends CoreMethodNode { - - public BreakNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public BreakNode(BreakNode prev) { - super(prev); - } - - @Specialization(order = 1) - public NilPlaceholder debugBreak(VirtualFrame frame, Node callNode, @SuppressWarnings("unused") UndefinedPlaceholder undefined0, @SuppressWarnings("unused") UndefinedPlaceholder undefined1, - @SuppressWarnings("unused") UndefinedPlaceholder block) { - getContext().runShell(callNode, frame.materialize()); - return NilPlaceholder.INSTANCE; - } - - @Specialization(order = 2) - public NilPlaceholder debugBreak(RubyString fileName, int line, @SuppressWarnings("unused") Node callNode, @SuppressWarnings("unused") UndefinedPlaceholder block) { - final RubyContext context = getContext(); - if (context.getConfiguration().getDebug()) { - final Source source = context.getSourceManager().get(fileName.toString()); - final SourceLineLocation lineLocation = new SourceLineLocation(source, line); - context.getRubyDebugManager().setBreakpoint(lineLocation, null); - } - return NilPlaceholder.INSTANCE; - } - - @Specialization(order = 3) - public NilPlaceholder debugBreak(RubyString fileName, int line, @SuppressWarnings("unused") Node callNode, RubyProc block) { - final RubyContext context = getContext(); - if (context.getConfiguration().getDebug()) { - final Source source = context.getSourceManager().get(fileName.toString()); - final SourceLineLocation lineLocation = new SourceLineLocation(source, line); - context.getRubyDebugManager().setBreakpoint(lineLocation, block); - } - return NilPlaceholder.INSTANCE; - } - - @Specialization(order = 4) - public NilPlaceholder debugBreak(RubySymbol methodName, RubySymbol localName, @SuppressWarnings("unused") Node callNode, @SuppressWarnings("unused") UndefinedPlaceholder block) { - final RubyContext context = getContext(); - if (context.getConfiguration().getDebug()) { - final RubyMethod method = context.getCoreLibrary().getMainObject().getLookupNode().lookupMethod(methodName.toString()); - final MethodLocal methodLocal = new MethodLocal(method.getUniqueIdentifier(), localName.toString()); - context.getRubyDebugManager().setBreakpoint(methodLocal, null); - } - return NilPlaceholder.INSTANCE; - } - - @Specialization(order = 5) - public NilPlaceholder debugBreak(RubySymbol methodName, RubySymbol localName, @SuppressWarnings("unused") Node callNode, RubyProc block) { - final RubyContext context = getContext(); - if (context.getConfiguration().getDebug()) { - final RubyMethod method = context.getCoreLibrary().getMainObject().getLookupNode().lookupMethod(methodName.toString()); - final MethodLocal methodLocal = new MethodLocal(method.getUniqueIdentifier(), localName.toString()); - context.getRubyDebugManager().setBreakpoint(methodLocal, block); - } - return NilPlaceholder.INSTANCE; - } - - } - - @CoreMethod(names = "continue", isModuleMethod = true, needsSelf = false, maxArgs = 0) - public abstract static class ContinueNode extends CoreMethodNode { - - public ContinueNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public ContinueNode(ContinueNode prev) { - super(prev); - } - - @Specialization - public Object debugContinue() { - if (getContext().getConfiguration().getDebug()) { - throw new BreakShellException(); - } - return NilPlaceholder.INSTANCE; - } - - } - - @CoreMethod(names = "enabled?", isModuleMethod = true, needsSelf = false, maxArgs = 0) - public abstract static class EnabledNode extends CoreMethodNode { - - public EnabledNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public EnabledNode(ContinueNode prev) { - super(prev); - } - - @Specialization - public boolean enabled() { - return getContext().getConfiguration().getDebug(); - } - - } - - @CoreMethod(names = "where", isModuleMethod = true, needsSelf = false, appendCallNode = true, minArgs = 1, maxArgs = 1) - public abstract static class WhereNode extends CoreMethodNode { - - public WhereNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public WhereNode(WhereNode prev) { - super(prev); - } - - @Specialization - public NilPlaceholder where(Node callNode) { - getContext().getConfiguration().getStandardOut().println(callNode.getSourceSection()); - return NilPlaceholder.INSTANCE; - } - - } - - @CoreMethod(names = "remove", isModuleMethod = true, needsSelf = false, needsBlock = true, minArgs = 2, maxArgs = 2) - public abstract static class RemoveNode extends CoreMethodNode { - - public RemoveNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - public RemoveNode(RemoveNode prev) { - super(prev); - } - - @Specialization - public NilPlaceholder debugRemove(RubyString fileName, int line) { - final RubyContext context = getContext(); - if (context.getConfiguration().getDebug()) { - final Source source = context.getSourceManager().get(fileName.toString()); - final SourceLineLocation lineLocation = new SourceLineLocation(source, line); - context.getRubyDebugManager().removeBreakpoint(lineLocation); - } - return NilPlaceholder.INSTANCE; - } - - @Specialization - public NilPlaceholder debugRemove(RubySymbol methodName, RubySymbol localName) { - final RubyContext context = getContext(); - if (context.getConfiguration().getDebug()) { - final RubyMethod method = context.getCoreLibrary().getMainObject().getLookupNode().lookupMethod(methodName.toString()); - final MethodLocal methodLocal = new MethodLocal(method.getUniqueIdentifier(), localName.toString()); - context.getRubyDebugManager().removeBreakpoint(methodLocal); - } - return NilPlaceholder.INSTANCE; - } - - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/debug/InactiveEnterDebugProbe.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/debug/InactiveEnterDebugProbe.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.debug; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.runtime.*; - -public abstract class InactiveEnterDebugProbe extends RubyProbe { - - private final Assumption inactiveAssumption; - - public InactiveEnterDebugProbe(RubyContext context, Assumption inactiveAssumption) { - super(context, false); - this.inactiveAssumption = inactiveAssumption; - } - - @Override - public void enter(Node astNode, VirtualFrame frame) { - try { - inactiveAssumption.check(); - } catch (InvalidAssumptionException e) { - final ActiveEnterDebugProbe activeNode = createActive(); - replace(activeNode); - activeNode.enter(astNode, frame); - } - } - - protected abstract ActiveEnterDebugProbe createActive(); - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/debug/InactiveLeaveDebugProbe.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/debug/InactiveLeaveDebugProbe.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.debug; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.runtime.*; - -public abstract class InactiveLeaveDebugProbe extends RubyProbe { - - private final Assumption inactiveAssumption; - - public InactiveLeaveDebugProbe(RubyContext context, Assumption inactiveAssumption) { - super(context, false); - this.inactiveAssumption = inactiveAssumption; - } - - @Override - public void leave(Node astNode, VirtualFrame frame, Object result) { - try { - inactiveAssumption.check(); - } catch (InvalidAssumptionException e) { - final ActiveLeaveDebugProbe activeNode = createActive(); - replace(activeNode); - activeNode.leave(astNode, frame, result); - } - } - - protected abstract ActiveLeaveDebugProbe createActive(); - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/debug/InactiveLineDebugProbe.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/debug/InactiveLineDebugProbe.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.debug; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.debug.*; - -public class InactiveLineDebugProbe extends InactiveEnterDebugProbe { - - private final SourceLineLocation sourceLine; - - public InactiveLineDebugProbe(RubyContext context, SourceLineLocation sourceLine, Assumption inactiveAssumption) { - super(context, inactiveAssumption); - this.sourceLine = sourceLine; - } - - @Override - protected ActiveEnterDebugProbe createActive() { - final RubyContext rubyContext = (RubyContext) getContext(); - final RubyDebugManager manager = rubyContext.getRubyDebugManager(); - return new ActiveLineDebugProbe(rubyContext, sourceLine, manager.getAssumption(sourceLine), manager.getBreakpoint(sourceLine)); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/debug/InactiveLocalDebugProbe.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/debug/InactiveLocalDebugProbe.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.debug; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.debug.*; - -public class InactiveLocalDebugProbe extends InactiveLeaveDebugProbe { - - private final MethodLocal methodLocal; - - public InactiveLocalDebugProbe(RubyContext context, MethodLocal methodLocal, Assumption inactiveAssumption) { - super(context, inactiveAssumption); - this.methodLocal = methodLocal; - } - - @Override - protected ActiveLeaveDebugProbe createActive() { - final RubyContext rubyContext = (RubyContext) getContext(); - final RubyDebugManager manager = rubyContext.getRubyDebugManager(); - return new ActiveLocalDebugProbe(rubyContext, methodLocal, manager.getAssumption(methodLocal), manager.getBreakpoint(methodLocal)); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/debug/RubyASTPrinter.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/debug/RubyASTPrinter.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,176 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.debug; - -import java.io.*; -import java.util.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.nodes.NodeUtil.NodeClass; -import com.oracle.truffle.api.nodes.NodeUtil.NodeField; -import com.oracle.truffle.api.nodes.NodeUtil.NodeFieldKind; -import com.oracle.truffle.api.nodes.instrument.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.nodes.call.CallNode; -import com.oracle.truffle.ruby.nodes.literal.*; -import com.oracle.truffle.ruby.nodes.methods.*; - -/** - * Printers for Truffle-internal AST information. - */ -public final class RubyASTPrinter implements ASTPrinter { - - public RubyASTPrinter() { - } - - public void printTree(PrintWriter p, Node node, int maxDepth, Node markNode) { - printTree(p, node, maxDepth, markNode, 1); - p.println(); - p.flush(); - } - - public String printTreeToString(Node node, int maxDepth, Node markNode) { - StringWriter out = new StringWriter(); - printTree(new PrintWriter(out), node, maxDepth, markNode); - return out.toString(); - } - - public String printTreeToString(Node node, int maxDepth) { - return printTreeToString(node, maxDepth, null); - } - - private static void printTree(PrintWriter p, Node node, int maxDepth, Node markNode, int level) { - if (node == null) { - p.print("null"); - return; - } - - p.print(nodeName(node)); - - String sep = ""; - p.print("("); - - final SourceSection src = node.getSourceSection(); - if (src != null) { - if (!(src instanceof NullSourceSection)) { - p.print(src.getSource().getName() + ":" + src.getStartLine()); - } else if (src instanceof CoreSourceSection) { - final CoreSourceSection coreSection = (CoreSourceSection) src; - p.print("core=\"" + (coreSection == null ? "?" : coreSection.toString()) + "\""); - } - } - if (node instanceof PhylumMarked) { - final PhylumMarked markedNode = (PhylumMarked) node; - String prefix = ""; - for (NodePhylum phylum : markedNode.getPhylumMarks()) { - p.print(prefix); - prefix = ","; - p.print(phylum.toString()); - } - - } - - ArrayList childFields = new ArrayList<>(); - - for (NodeField field : NodeClass.get(node.getClass()).getFields()) { - if (field.getKind() == NodeFieldKind.CHILD || field.getKind() == NodeFieldKind.CHILDREN) { - childFields.add(field); - } else if (field.getKind() == NodeFieldKind.DATA) { - // p.print(sep); - // sep = ", "; - // - // final String fieldName = field.getName(); - // switch (fieldName) { - // - // } - // p.print(fieldName); - // p.print(" = "); - // p.print(field.loadValue(node)); - } - } - p.print(")"); - - if (level <= maxDepth) { - - if (childFields.size() != 0) { - p.print(" {"); - for (NodeField field : childFields) { - - Object value = field.loadValue(node); - if (value == null) { - printNewLine(p, level); - p.print(field.getName()); - p.print(" = null "); - } else if (field.getKind() == NodeFieldKind.CHILD) { - final Node valueNode = (Node) value; - printNewLine(p, level, valueNode == markNode); - p.print(field.getName()); - p.print(" = "); - printTree(p, valueNode, maxDepth, markNode, level + 1); - } else if (field.getKind() == NodeFieldKind.CHILDREN) { - printNewLine(p, level); - p.print(field.getName()); - Node[] children = (Node[]) value; - p.print(" = ["); - sep = ""; - for (Node child : children) { - p.print(sep); - sep = ", "; - printTree(p, child, maxDepth, markNode, level + 1); - } - p.print("]"); - } else { - printNewLine(p, level); - p.print(field.getName()); - } - } - printNewLine(p, level - 1); - p.print("}"); - } - } - } - - private static void printNewLine(PrintWriter p, int level, boolean mark) { - p.println(); - for (int i = 0; i < level; i++) { - if (mark && i == 0) { - p.print(" -->"); - } else { - p.print(" "); - } - } - } - - private static void printNewLine(PrintWriter p, int level) { - printNewLine(p, level, false); - } - - private static String nodeName(Node node) { - String nodeVal = null; - if (node instanceof CallNode) { - final CallNode callNode = (CallNode) node; - nodeVal = callNode.getName(); - - } else if (node instanceof FixnumLiteralNode) { - final FixnumLiteralNode fixnum = (FixnumLiteralNode) node; - nodeVal = Integer.toString(fixnum.getValue()); - } else if (node instanceof MethodDefinitionNode) { - final MethodDefinitionNode defNode = (MethodDefinitionNode) node; - nodeVal = defNode.getName(); - } - String result = node.getClass().getSimpleName(); - if (nodeVal != null) { - result = result + "[\"" + nodeVal + "\"]"; - } - return result; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/debug/RubyProbe.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/debug/RubyProbe.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.debug; - -import com.oracle.truffle.api.nodes.instrument.*; -import com.oracle.truffle.ruby.runtime.*; - -/** - * A "probe node" implemented specifically for the Ruby implementation; subclasses need only - * override those members of {@link InstrumentationProbeEvents} for which some action is needed. - */ -public abstract class RubyProbe extends InstrumentationProbeNode.DefaultProbeNode { - - protected final boolean oneShot; - - protected final RubyContext context; - - /** - * OneShot is this a one-shot (self-removing) probe? - */ - public RubyProbe(RubyContext context, boolean oneShot) { - super(context); - this.oneShot = oneShot; - this.context = context; - } - - /** - * Is this a one-shot (self-removing) probe? If so, it will remove itself the first time - * activated. - */ - public boolean isOneShot() { - return oneShot; - } -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/debug/RubyProxyNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/debug/RubyProxyNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,229 +0,0 @@ -/* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.debug; - -import java.math.*; -import java.util.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.nodes.instrument.*; -import com.oracle.truffle.api.nodes.instrument.InstrumentationProbeNode.ProbeChain; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.control.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.core.array.*; - -/** - * An instrumentation proxy node that forwards all Ruby execution calls through to - * a child node and returns results back to the parent, but which also sends notifications to an - * attached {@linkplain ProbeChain chain} of {@linkplain InstrumentationProbeNode probes}. - */ -public class RubyProxyNode extends RubyNode implements InstrumentationProxyNode { - - @Child private RubyNode child; - - private final ProbeChain probeChain; - - public RubyProxyNode(RubyContext context, RubyNode child) { - super(context, SourceSection.NULL); - assert !(child instanceof RubyProxyNode); - this.child = adoptChild(child); - this.probeChain = context.getDebugManager().getProbeChain(child.getSourceSection()); - } - - public RubyProxyNode(RubyContext context, RubyNode child, ProbeChain probeChain) { - super(context, SourceSection.NULL); - assert !(child instanceof RubyProxyNode); - this.child = adoptChild(child); - this.probeChain = probeChain; - } - - @Override - public RubyNode getNonProxyNode() { - return child; - } - - public RubyNode getChild() { - return child; - } - - public ProbeChain getProbeChain() { - return probeChain; - } - - @Override - public Object execute(VirtualFrame frame) { - probeChain.notifyEnter(child, frame); - - Object result; - - try { - result = child.execute(frame); - probeChain.notifyLeave(child, frame, result); - } catch (BreakShellException e) { - throw (e); - } catch (Exception e) { - probeChain.notifyLeaveExceptional(child, frame, e); - throw (e); - } - - return result; - } - - @Override - public RubyArray executeArray(VirtualFrame frame) throws UnexpectedResultException { - probeChain.notifyEnter(child, frame); - - RubyArray result; - - try { - result = child.executeArray(frame); - probeChain.notifyLeave(child, frame, result); - } catch (BreakShellException e) { - throw (e); - } catch (Exception e) { - probeChain.notifyLeaveExceptional(child, frame, e); - throw (e); - } - - return result; - } - - @Override - public BigInteger executeBignum(VirtualFrame frame) throws UnexpectedResultException { - probeChain.notifyEnter(child, frame); - - BigInteger result; - - try { - result = child.executeBignum(frame); - probeChain.notifyLeave(child, frame, result); - } catch (BreakShellException e) { - throw (e); - } catch (Exception e) { - probeChain.notifyLeaveExceptional(child, frame, e); - throw (e); - } - - return result; - } - - @Override - public boolean executeBoolean(VirtualFrame frame) throws UnexpectedResultException { - probeChain.notifyEnter(child, frame); - - boolean result; - - try { - result = child.executeBoolean(frame); - probeChain.notifyLeave(child, frame, result); - } catch (BreakShellException e) { - throw (e); - } catch (Exception e) { - probeChain.notifyLeaveExceptional(child, frame, e); - throw (e); - } - - return result; - } - - @Override - public Object isDefined(VirtualFrame frame) { - return child.isDefined(frame); - } - - @Override - public int executeFixnum(VirtualFrame frame) throws UnexpectedResultException { - probeChain.notifyEnter(child, frame); - - int result; - - try { - result = child.executeFixnum(frame); - probeChain.notifyLeave(child, frame, result); - } catch (BreakShellException e) { - throw (e); - } catch (Exception e) { - probeChain.notifyLeaveExceptional(child, frame, e); - throw (e); - } - - return result; - } - - @Override - public double executeFloat(VirtualFrame frame) throws UnexpectedResultException { - probeChain.notifyEnter(child, frame); - - double result; - - try { - result = child.executeFloat(frame); - probeChain.notifyLeave(child, frame, result); - } catch (BreakShellException e) { - throw (e); - } catch (Exception e) { - probeChain.notifyLeaveExceptional(child, frame, e); - throw (e); - } - - return result; - } - - @Override - public RubyString executeString(VirtualFrame frame) throws UnexpectedResultException { - probeChain.notifyEnter(child, frame); - - RubyString result; - - try { - result = child.executeString(frame); - probeChain.notifyLeave(child, frame, result); - } catch (BreakShellException e) { - throw (e); - } catch (Exception e) { - probeChain.notifyLeaveExceptional(child, frame, e); - throw (e); - } - - return result; - } - - @Override - public void executeVoid(VirtualFrame frame) { - probeChain.notifyEnter(child, frame); - - try { - child.executeVoid(frame); - probeChain.notifyLeave(child, frame); - } catch (BreakShellException e) { - throw (e); - } catch (Exception e) { - probeChain.notifyLeaveExceptional(child, frame, e); - throw (e); - } - } - - public boolean isMarkedAs(NodePhylum phylum) { - return probeChain.isMarkedAs(phylum); - } - - public Set getPhylumMarks() { - return probeChain.getPhylumMarks(); - } - - public void markAs(NodePhylum phylum) { - probeChain.markAs(phylum); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/debug/RubyTraceProbe.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/debug/RubyTraceProbe.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.debug; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.subsystems.*; - -/** - * A "trace" probe that has no runtime cost until activated, at which time it invokes a trace - * message. - */ -public final class RubyTraceProbe extends RubyProbe { - - private final Assumption notTracingAssumption; - - @CompilerDirectives.CompilationFinal private boolean tracingEverEnabled = false; - - public RubyTraceProbe(RubyContext context) { - super(context, false); - this.notTracingAssumption = context.getTraceManager().getNotTracingAssumption(); - } - - @Override - public void enter(Node astNode, VirtualFrame frame) { - if (!tracingEverEnabled) { - try { - notTracingAssumption.check(); - } catch (InvalidAssumptionException e) { - tracingEverEnabled = true; - } - } - final TraceManager traceManager = context.getTraceManager(); - if (tracingEverEnabled && traceManager.hasTraceProc()) { - final SourceSection sourceSection = astNode.getEncapsulatingSourceSection(); - traceManager.trace("line", sourceSection.getSource().getName(), sourceSection.getStartLine(), 0, null, null); - } - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/literal/BignumLiteralNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/literal/BignumLiteralNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.literal; - -import java.math.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; - -@NodeInfo(shortName = "bignum") -public class BignumLiteralNode extends RubyNode { - - private final BigInteger value; - - public BignumLiteralNode(RubyContext context, SourceSection sourceSection, BigInteger value) { - super(context, sourceSection); - this.value = value; - } - - @Override - public BigInteger executeBignum(VirtualFrame frame) { - return value; - } - - @Override - public Object execute(VirtualFrame frame) { - return value; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/literal/BooleanLiteralNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/literal/BooleanLiteralNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.literal; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; - -@NodeInfo(shortName = "boolean") -public class BooleanLiteralNode extends RubyNode { - - private final boolean value; - - public BooleanLiteralNode(RubyContext context, SourceSection sourceSection, boolean value) { - super(context, sourceSection); - this.value = value; - } - - @Override - public Object execute(VirtualFrame frame) { - return executeBoolean(frame); - } - - @Override - public boolean executeBoolean(VirtualFrame frame) { - return value; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/literal/FixnumLiteralNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/literal/FixnumLiteralNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.literal; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; - -@NodeInfo(shortName = "fixnum") -public class FixnumLiteralNode extends RubyNode { - - private final int value; - - public FixnumLiteralNode(RubyContext context, SourceSection sourceSection, int value) { - super(context, sourceSection); - this.value = value; - } - - @Override - public Object execute(VirtualFrame frame) { - return executeFixnum(frame); - } - - @Override - public int executeFixnum(VirtualFrame frame) { - return value; - } - - public int getValue() { - return value; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/literal/FloatLiteralNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/literal/FloatLiteralNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.literal; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; - -@NodeInfo(shortName = "float") -public class FloatLiteralNode extends RubyNode { - - private final double value; - - public FloatLiteralNode(RubyContext context, SourceSection sourceSection, double value) { - super(context, sourceSection); - this.value = value; - } - - @Override - public Object execute(VirtualFrame frame) { - return executeFloat(frame); - } - - @Override - public double executeFloat(VirtualFrame frame) { - return value; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/literal/HashLiteralNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/literal/HashLiteralNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.literal; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; - -@NodeInfo(shortName = "hash") -public class HashLiteralNode extends RubyNode { - - @Children protected final RubyNode[] keys; - @Children protected final RubyNode[] values; - - public HashLiteralNode(SourceSection sourceSection, RubyNode[] keys, RubyNode[] values, RubyContext context) { - super(context, sourceSection); - assert keys.length == values.length; - this.keys = adoptChildren(keys); - this.values = adoptChildren(values); - } - - @ExplodeLoop - @Override - public Object execute(VirtualFrame frame) { - final RubyHash hash = new RubyHash(getContext().getCoreLibrary().getHashClass()); - - for (int n = 0; n < keys.length; n++) { - hash.put(keys[n].execute(frame), values[n].execute(frame)); - } - - return hash; - } - - @Override - public Object isDefined(VirtualFrame frame) { - return getContext().makeString("expression"); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/literal/NilNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/literal/NilNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.literal; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; - -/** - * A node that does nothing and evaluates to Nil. A no-op. - */ -@NodeInfo(shortName = "nil") -public final class NilNode extends RubyNode { - - public NilNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - @Override - public NilPlaceholder executeNilPlaceholder(VirtualFrame frame) { - return NilPlaceholder.INSTANCE; - } - - @Override - public Object execute(VirtualFrame frame) { - return executeNilPlaceholder(frame); - } - - @Override - public void executeVoid(VirtualFrame frame) { - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/literal/ObjectLiteralNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/literal/ObjectLiteralNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.literal; - -import java.math.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; - -@NodeInfo(shortName = "object") -public class ObjectLiteralNode extends RubyNode { - - private final Object object; - - public ObjectLiteralNode(RubyContext context, SourceSection sourceSection, Object object) { - super(context, sourceSection); - - assert RubyContext.shouldObjectBeVisible(object); - assert !(object instanceof Integer); - assert !(object instanceof Double); - assert !(object instanceof BigInteger); - assert !(object instanceof String); - assert !(object instanceof RubyString); - - this.object = object; - } - - @Override - public Object execute(VirtualFrame frame) { - return object; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/literal/RangeLiteralNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/literal/RangeLiteralNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.literal; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.range.*; - -@NodeInfo(shortName = "range") -@NodeChildren({@NodeChild("begin"), @NodeChild("end")}) -public abstract class RangeLiteralNode extends RubyNode { - - private final boolean excludeEnd; - - public RangeLiteralNode(RubyContext context, SourceSection sourceSection, boolean excludeEnd) { - super(context, sourceSection); - this.excludeEnd = excludeEnd; - } - - public RangeLiteralNode(RangeLiteralNode prev) { - this(prev.getContext(), prev.getSourceSection(), prev.excludeEnd); - } - - @Specialization - public FixnumRange doFixnum(int begin, int end) { - return new FixnumRange(getContext().getCoreLibrary().getRangeClass(), begin, end, excludeEnd); - } - - @Generic - public Object doGeneric(Object begin, Object end) { - final RubyContext context = getContext(); - - if ((begin instanceof Integer) && (end instanceof Integer)) { - return doFixnum((int) begin, (int) end); - } else { - return new ObjectRange(context.getCoreLibrary().getRangeClass(), begin, end, excludeEnd); - } - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/literal/StringLiteralNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/literal/StringLiteralNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.literal; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; - -@NodeInfo(shortName = "string") -public class StringLiteralNode extends RubyNode { - - private final String string; - - public StringLiteralNode(RubyContext context, SourceSection sourceSection, String string) { - super(context, sourceSection); - - assert string != null; - - this.string = string; - } - - @Override - public Object execute(VirtualFrame frame) { - return getContext().makeString(string); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/literal/array/ArrayLiteralNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/literal/array/ArrayLiteralNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.literal.array; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.array.*; - -public abstract class ArrayLiteralNode extends RubyNode { - - @Children protected final RubyNode[] values; - - public ArrayLiteralNode(RubyContext context, SourceSection sourceSection, RubyNode[] values) { - super(context, sourceSection); - this.values = adoptChildren(values); - } - - protected RubyArray makeGeneric(VirtualFrame frame, Object[] alreadyExecuted) { - CompilerAsserts.neverPartOfCompilation(); - - replace(new ObjectArrayLiteralNode(getContext(), getSourceSection(), values)); - - final Object[] executedValues = new Object[values.length]; - - for (int n = 0; n < values.length; n++) { - if (n < alreadyExecuted.length) { - executedValues[n] = alreadyExecuted[n]; - } else { - executedValues[n] = values[n].execute(frame); - } - } - - return RubyArray.specializedFromObjects(getContext().getCoreLibrary().getArrayClass(), executedValues); - } - - @Override - public Object isDefined(VirtualFrame frame) { - return getContext().makeString("expression"); - } - - // TODO(CS): remove this - shouldn't be fiddling with nodes from the outside - public RubyNode[] getValues() { - return values; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/literal/array/FixnumArrayLiteralNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/literal/array/FixnumArrayLiteralNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.literal.array; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.array.*; - -@NodeInfo(shortName = "fixnum-array-literal") -public class FixnumArrayLiteralNode extends ArrayLiteralNode { - - public FixnumArrayLiteralNode(RubyContext context, SourceSection sourceSection, RubyNode[] values) { - super(context, sourceSection, values); - } - - @ExplodeLoop - @Override - public RubyArray executeArray(VirtualFrame frame) { - final int[] executedValues = new int[values.length]; - - for (int n = 0; n < values.length; n++) { - try { - executedValues[n] = values[n].executeFixnum(frame); - } catch (UnexpectedResultException e) { - final Object[] executedObjects = new Object[n]; - - for (int i = 0; i < n; i++) { - executedObjects[i] = executedValues[i]; - } - - return makeGeneric(frame, executedObjects); - } - } - - return new RubyArray(getContext().getCoreLibrary().getArrayClass(), new FixnumArrayStore(executedValues)); - } - - @ExplodeLoop - @Override - public void executeVoid(VirtualFrame frame) { - for (int n = 0; n < values.length; n++) { - values[n].executeVoid(frame); - } - } - - @Override - public Object execute(VirtualFrame frame) { - return executeArray(frame); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/literal/array/ObjectArrayLiteralNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/literal/array/ObjectArrayLiteralNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.literal.array; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.array.*; - -@NodeInfo(shortName = "object-array-literal") -public class ObjectArrayLiteralNode extends ArrayLiteralNode { - - public ObjectArrayLiteralNode(RubyContext context, SourceSection sourceSection, RubyNode[] values) { - super(context, sourceSection, values); - } - - @ExplodeLoop - @Override - public RubyArray executeArray(VirtualFrame frame) { - final Object[] executedValues = new Object[values.length]; - - for (int n = 0; n < values.length; n++) { - executedValues[n] = values[n].execute(frame); - } - - return new RubyArray(getContext().getCoreLibrary().getArrayClass(), new ObjectArrayStore(executedValues)); - } - - @ExplodeLoop - @Override - public void executeVoid(VirtualFrame frame) { - for (int n = 0; n < values.length; n++) { - values[n].executeVoid(frame); - } - } - - @Override - public Object execute(VirtualFrame frame) { - return executeArray(frame); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/literal/array/UninitialisedArrayLiteralNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/literal/array/UninitialisedArrayLiteralNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.literal.array; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.array.*; - -@NodeInfo(shortName = "uninit-array-literal") -public class UninitialisedArrayLiteralNode extends ArrayLiteralNode { - - public UninitialisedArrayLiteralNode(RubyContext context, SourceSection sourceSection, RubyNode[] values) { - super(context, sourceSection, values); - } - - @ExplodeLoop - @Override - public Object execute(VirtualFrame frame) { - CompilerDirectives.transferToInterpreter(); - - final Object[] executedValues = new Object[values.length]; - - for (int n = 0; n < values.length; n++) { - executedValues[n] = values[n].execute(frame); - } - - final RubyArray array = RubyArray.specializedFromObjects(getContext().getCoreLibrary().getArrayClass(), executedValues); - final ArrayStore store = array.getArrayStore(); - - if (store instanceof FixnumArrayStore) { - replace(new FixnumArrayLiteralNode(getContext(), getSourceSection(), values)); - } else { - replace(new ObjectArrayLiteralNode(getContext(), getSourceSection(), values)); - } - - return array; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/AddMethodNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/AddMethodNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.methods; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.methods.*; - -@NodeInfo(shortName = "add-method") -public class AddMethodNode extends RubyNode { - - @Child protected RubyNode receiver; - @Child protected MethodDefinitionNode method; - - public AddMethodNode(RubyContext context, SourceSection section, RubyNode receiver, MethodDefinitionNode method) { - super(context, section); - this.receiver = adoptChild(receiver); - this.method = adoptChild(method); - } - - @Override - public Object execute(VirtualFrame frame) { - final Object receiverObject = receiver.execute(frame); - - final RubyMethod methodObject = (RubyMethod) method.execute(frame); - - final FrameSlot moduleFunctionFlagSlot = frame.getFrameDescriptor().findFrameSlot(RubyModule.MODULE_FUNCTION_FLAG_FRAME_SLOT_ID); - - boolean moduleFunctionFlag; - - if (moduleFunctionFlagSlot == null) { - moduleFunctionFlag = false; - } else { - Object moduleFunctionObject; - - try { - moduleFunctionObject = frame.getObject(moduleFunctionFlagSlot); - } catch (FrameSlotTypeException e) { - throw new RuntimeException(e); - } - - if (moduleFunctionObject instanceof Boolean) { - moduleFunctionFlag = (boolean) moduleFunctionObject; - } else { - moduleFunctionFlag = false; - } - } - - final RubyModule module = (RubyModule) receiverObject; - - final RubyMethod methodWithDeclaringModule = methodObject.withDeclaringModule(module); - - module.addMethod(methodWithDeclaringModule); - - if (moduleFunctionFlag) { - module.getSingletonClass().addMethod(methodWithDeclaringModule); - } - - return NilPlaceholder.INSTANCE; - } -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/AliasNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/AliasNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.methods; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; - -@NodeInfo(shortName = "alias") -public class AliasNode extends RubyNode { - - @Child protected RubyNode module; - final String newName; - final String oldName; - - public AliasNode(RubyContext context, SourceSection sourceSection, RubyNode module, String newName, String oldName) { - super(context, sourceSection); - this.module = adoptChild(module); - this.newName = newName; - this.oldName = oldName; - } - - @Override - public void executeVoid(VirtualFrame frame) { - final RubyModule moduleObject = (RubyModule) module.execute(frame); - moduleObject.alias(newName, oldName); - } - - @Override - public Object execute(VirtualFrame frame) { - executeVoid(frame); - return NilPlaceholder.INSTANCE; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/BlockDefinitionNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/BlockDefinitionNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.methods; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.methods.*; - -/** - * Define a block. That is, store the definition of a block and when executed produce the executable - * object that results. - */ -@NodeInfo(shortName = "block-def") -public class BlockDefinitionNode extends MethodDefinitionNode { - - public BlockDefinitionNode(RubyContext context, SourceSection sourceSection, String name, UniqueMethodIdentifier uniqueIdentifier, FrameDescriptor frameDescriptor, - boolean requiresDeclarationFrame, RubyRootNode pristineRootNode, CallTarget callTarget) { - super(context, sourceSection, name, uniqueIdentifier, frameDescriptor, requiresDeclarationFrame, pristineRootNode, callTarget); - } - - @Override - public Object execute(VirtualFrame frame) { - final RubyContext context = getContext(); - - MaterializedFrame declarationFrame; - - if (requiresDeclarationFrame) { - declarationFrame = frame.materialize(); - } else { - declarationFrame = null; - } - - final RubyArguments arguments = frame.getArguments(RubyArguments.class); - - final InlinableMethodImplementation methodImplementation = new InlinableMethodImplementation(callTarget, declarationFrame, frameDescriptor, pristineRootNode, true, false); - final RubyMethod method = new RubyMethod(getSourceSection(), null, uniqueIdentifier, null, name, Visibility.PUBLIC, false, methodImplementation); - - return new RubyProc(context.getCoreLibrary().getProcClass(), RubyProc.Type.PROC, arguments.getSelf(), arguments.getBlock(), method); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/CatchNextNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/CatchNextNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.methods; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.utilities.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.control.*; - -/** - * Catch a {@code next} jump at the root of a method. - */ -public class CatchNextNode extends RubyNode { - - @Child protected RubyNode body; - - private final BranchProfile nextProfile = new BranchProfile(); - - public CatchNextNode(RubyContext context, SourceSection sourceSection, RubyNode body) { - super(context, sourceSection); - this.body = adoptChild(body); - } - - @Override - public Object execute(VirtualFrame frame) { - try { - return body.execute(frame); - } catch (NextException e) { - nextProfile.enter(); - return e.getResult(); - } - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/CatchReturnAsErrorNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/CatchReturnAsErrorNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.methods; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.control.*; - -/** - * Catch a {@code return} jump at the root of a method, and report it as an error. - */ -public class CatchReturnAsErrorNode extends RubyNode { - - @Child protected RubyNode body; - - public CatchReturnAsErrorNode(RubyContext context, SourceSection sourceSection, RubyNode body) { - super(context, sourceSection); - this.body = adoptChild(body); - } - - @Override - public Object execute(VirtualFrame frame) { - try { - return body.execute(frame); - } catch (ReturnException e) { - CompilerDirectives.transferToInterpreter(); - throw new RaiseException(getContext().getCoreLibrary().unexpectedReturn()); - } - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/CatchReturnNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/CatchReturnNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.methods; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.utilities.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.control.*; - -/** - * Catch a {@code return} jump at the root of a method. - */ -public class CatchReturnNode extends RubyNode { - - @Child protected RubyNode body; - private final long returnID; - - private final BranchProfile returnProfile = new BranchProfile(); - private final BranchProfile returnToOtherMethodProfile = new BranchProfile(); - - public CatchReturnNode(RubyContext context, SourceSection sourceSection, RubyNode body, long returnID) { - super(context, sourceSection); - this.body = adoptChild(body); - this.returnID = returnID; - } - - public CatchReturnNode(CatchReturnNode prev) { - super(prev); - returnID = prev.returnID; - } - - @Override - public Object execute(VirtualFrame frame) { - try { - return body.execute(frame); - } catch (ReturnException e) { - returnProfile.enter(); - - if (e.getReturnID() == returnID) { - return e.getValue(); - } else { - returnToOtherMethodProfile.enter(); - throw e; - } - } - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/MethodDefinitionNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/MethodDefinitionNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,98 +0,0 @@ -/* - * Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.methods; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.methods.*; - -/** - * Define a method. That is, store the definition of a method and when executed produce the - * executable object that results. - */ -@NodeInfo(shortName = "method-def") -public class MethodDefinitionNode extends RubyNode { - - protected final String name; - protected final UniqueMethodIdentifier uniqueIdentifier; - - protected final FrameDescriptor frameDescriptor; - protected final RubyRootNode pristineRootNode; - - protected final CallTarget callTarget; - - protected final boolean requiresDeclarationFrame; - - public MethodDefinitionNode(RubyContext context, SourceSection sourceSection, String name, UniqueMethodIdentifier uniqueIdentifier, FrameDescriptor frameDescriptor, - boolean requiresDeclarationFrame, RubyRootNode pristineRootNode, CallTarget callTarget) { - super(context, sourceSection); - this.name = name; - this.uniqueIdentifier = uniqueIdentifier; - this.frameDescriptor = frameDescriptor; - this.requiresDeclarationFrame = requiresDeclarationFrame; - this.pristineRootNode = pristineRootNode; - this.callTarget = callTarget; - } - - public RubyMethod executeMethod(VirtualFrame frame) { - CompilerDirectives.transferToInterpreter(); - - MaterializedFrame declarationFrame; - - if (requiresDeclarationFrame) { - declarationFrame = frame.materialize(); - } else { - declarationFrame = null; - } - - final FrameSlot visibilitySlot = frame.getFrameDescriptor().findFrameSlot(RubyModule.VISIBILITY_FRAME_SLOT_ID); - - Visibility visibility; - - if (visibilitySlot == null) { - visibility = Visibility.PUBLIC; - } else { - Object visibilityObject; - - try { - visibilityObject = frame.getObject(visibilitySlot); - } catch (FrameSlotTypeException e) { - throw new RuntimeException(e); - } - - if (visibilityObject instanceof Visibility) { - visibility = (Visibility) visibilityObject; - } else { - visibility = Visibility.PUBLIC; - } - } - - final InlinableMethodImplementation methodImplementation = new InlinableMethodImplementation(callTarget, declarationFrame, frameDescriptor, pristineRootNode, false, false); - return new RubyMethod(getSourceSection(), null, uniqueIdentifier, null, name, visibility, false, methodImplementation); - } - - @Override - public Object execute(VirtualFrame frame) { - return executeMethod(frame); - } - - public String getName() { - return name; - } - - public CallTarget getCallTarget() { - return callTarget; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/ShellResultNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/ShellResultNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.methods; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; - -/** - * Produce a {@link ShellResult} object from a return value and the resulting frame. - */ -public class ShellResultNode extends RubyNode { - - @Child protected RubyNode body; - - public ShellResultNode(RubyContext context, SourceSection sourceSection, RubyNode body) { - super(context, sourceSection); - this.body = adoptChild(body); - } - - @Override - public Object execute(VirtualFrame frame) { - return new ShellResult(body.execute(frame), frame.materialize()); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/arguments/BlockDestructureSwitchNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/arguments/BlockDestructureSwitchNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.methods.arguments; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.array.*; - -/** - * Switches between loading arguments as normal and doing a destructure. See - * testBlockArgumentsDestructure and MethodTranslator. - */ -@NodeInfo(shortName = "block-destructure-switch") -public class BlockDestructureSwitchNode extends RubyNode { - - @Child protected RubyNode loadIndividualArguments; - @Child protected RubyNode destructureArguments; - @Child protected RubyNode body; - - public BlockDestructureSwitchNode(RubyContext context, SourceSection sourceSection, RubyNode loadIndividualArguments, RubyNode destructureArguments, RubyNode body) { - super(context, sourceSection); - this.loadIndividualArguments = adoptChild(loadIndividualArguments); - this.destructureArguments = adoptChild(destructureArguments); - this.body = adoptChild(body); - } - - @Override - public Object execute(VirtualFrame frame) { - final RubyArguments arguments = frame.getArguments(RubyArguments.class); - - if (arguments.getArguments().length == 1 && arguments.getArguments()[0] instanceof RubyArray) { - destructureArguments.executeVoid(frame); - } else { - loadIndividualArguments.executeVoid(frame); - } - - return body.execute(frame); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/arguments/CheckArityNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/arguments/CheckArityNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.methods.arguments; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.methods.*; - -/** - * Check arguments meet the arity of the method. - */ -@NodeInfo(shortName = "check-arity") -public class CheckArityNode extends RubyNode { - - private final Arity arity; - - public CheckArityNode(RubyContext context, SourceSection sourceSection, Arity arity) { - super(context, sourceSection); - this.arity = arity; - } - - @Override - public void executeVoid(VirtualFrame frame) { - final RubyArguments arguments = frame.getArguments(RubyArguments.class); - arity.checkArguments(getContext(), arguments.getArguments()); - } - - @Override - public Object execute(VirtualFrame frame) { - executeVoid(frame); - return NilPlaceholder.INSTANCE; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/arguments/ReadAllArgumentsNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/arguments/ReadAllArgumentsNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.methods.arguments; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; - -public class ReadAllArgumentsNode extends RubyNode { - - public ReadAllArgumentsNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - @Override - public Object[] executeObjectArray(VirtualFrame frame) { - return frame.getArguments(RubyArguments.class).getArguments(); - } - - @Override - public Object execute(VirtualFrame frame) { - return executeObjectArray(frame); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/arguments/ReadBlockArgumentNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/arguments/ReadBlockArgumentNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.methods.arguments; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; - -/** - * Read the block as a {@code Proc}. - */ -@NodeInfo(shortName = "read-block-argument") -public class ReadBlockArgumentNode extends RubyNode { - - private final boolean undefinedIfNotPresent; - - public ReadBlockArgumentNode(RubyContext context, SourceSection sourceSection, boolean undefinedIfNotPresent) { - super(context, sourceSection); - this.undefinedIfNotPresent = undefinedIfNotPresent; - } - - @Override - public Object execute(VirtualFrame frame) { - final RubyArguments arguments = frame.getArguments(RubyArguments.class); - final RubyProc block = arguments.getBlock(); - - if (block == null) { - if (undefinedIfNotPresent) { - return UndefinedPlaceholder.INSTANCE; - } else { - return NilPlaceholder.INSTANCE; - } - } else { - return block; - } - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/arguments/ReadDestructureArgumentNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/arguments/ReadDestructureArgumentNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.methods.arguments; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.array.*; - -/** - * Assuming argument 0 is an array, read an element from that array. - */ -@NodeInfo(shortName = "read-destructure-argument") -public class ReadDestructureArgumentNode extends RubyNode { - - private final int index; - - public ReadDestructureArgumentNode(RubyContext context, SourceSection sourceSection, int index) { - super(context, sourceSection); - this.index = index; - } - - @Override - public Object execute(VirtualFrame frame) { - final RubyArray array = (RubyArray) frame.getArguments(RubyArguments.class).getArguments()[0]; - return array.get(index); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/arguments/ReadOptionalArgumentNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/arguments/ReadOptionalArgumentNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.methods.arguments; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.utilities.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; - -/** - * Read an optional argument. - */ -@NodeInfo(shortName = "read-optional-argument") -public class ReadOptionalArgumentNode extends RubyNode { - - private final int index; - private final int minimum; - @Child protected RubyNode defaultValue; - - private final BranchProfile defaultValueProfile = new BranchProfile(); - - public ReadOptionalArgumentNode(RubyContext context, SourceSection sourceSection, int index, int minimum, RubyNode defaultValue) { - super(context, sourceSection); - this.index = index; - this.minimum = minimum; - this.defaultValue = adoptChild(defaultValue); - } - - @Override - public Object execute(VirtualFrame frame) { - final Object[] arguments = frame.getArguments(RubyArguments.class).getArguments(); - - if (arguments.length < minimum) { - defaultValueProfile.enter(); - return defaultValue.execute(frame); - } else { - assert index < arguments.length; - return arguments[index]; - } - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/arguments/ReadPostArgumentNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/arguments/ReadPostArgumentNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.methods.arguments; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; - -/** - * Read a post-optional argument. - */ -@NodeInfo(shortName = "read-post-optional-argument") -public class ReadPostArgumentNode extends RubyNode { - - private final int indexFromEnd; - - public ReadPostArgumentNode(RubyContext context, SourceSection sourceSection, int indexFromEnd) { - super(context, sourceSection); - this.indexFromEnd = indexFromEnd; - } - - @Override - public Object execute(VirtualFrame frame) { - final Object[] arguments = frame.getArguments(RubyArguments.class).getArguments(); - final int effectiveIndex = arguments.length - 1 - indexFromEnd; - assert effectiveIndex < arguments.length; - return arguments[effectiveIndex]; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/arguments/ReadPreArgumentNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/arguments/ReadPreArgumentNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.methods.arguments; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.utilities.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; - -/** - * Read pre-optional argument. - */ -@NodeInfo(shortName = "read-pre-optional-argument") -public class ReadPreArgumentNode extends RubyNode { - - private final int index; - private final boolean undefinedIfNotPresent; - - private final BranchProfile notPresentProfile = new BranchProfile(); - - public ReadPreArgumentNode(RubyContext context, SourceSection sourceSection, int index, boolean undefinedIfNotPresent) { - super(context, sourceSection); - this.index = index; - this.undefinedIfNotPresent = undefinedIfNotPresent; - } - - @Override - public Object execute(VirtualFrame frame) { - final Object[] arguments = frame.getArguments(RubyArguments.class).getArguments(); - - if (undefinedIfNotPresent) { - if (index >= arguments.length) { - notPresentProfile.enter(); - return UndefinedPlaceholder.INSTANCE; - } - } else { - assert index < arguments.length; - } - - return arguments[index]; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/arguments/ReadRestArgumentNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/arguments/ReadRestArgumentNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.methods.arguments; - -import java.util.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.core.array.*; - -/** - * Read the rest of arguments after a certain point into an array. - */ -@NodeInfo(shortName = "read-rest-of-arguments") -public class ReadRestArgumentNode extends RubyNode { - - private final int index; - - public ReadRestArgumentNode(RubyContext context, SourceSection sourceSection, int index) { - super(context, sourceSection); - this.index = index; - } - - @Override - public Object execute(VirtualFrame frame) { - final RubyArguments rubyArguments = frame.getArguments(RubyArguments.class); - - final Object[] arguments = rubyArguments.getArguments(); - - final RubyClass arrayClass = getContext().getCoreLibrary().getArrayClass(); - - if (arguments.length <= index) { - return new RubyArray(arrayClass); - } else if (index == 0) { - return new RubyArray(arrayClass, new ObjectArrayStore(arguments)); - } else { - return new RubyArray(arrayClass, new ObjectArrayStore(Arrays.copyOfRange(arguments, index, arguments.length))); - } - } -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/locals/FlipFlopStateNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/locals/FlipFlopStateNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.methods.locals; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; - -public abstract class FlipFlopStateNode extends Node { - - public FlipFlopStateNode(SourceSection sourceSection) { - super(sourceSection); - } - - public abstract boolean getState(VirtualFrame frame); - - public abstract void setState(VirtualFrame frame, boolean state); - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/locals/FrameSlotNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/locals/FrameSlotNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.methods.locals; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; - -public abstract class FrameSlotNode extends RubyNode { - - protected final FrameSlot frameSlot; - - protected FrameSlotNode(RubyContext context, SourceSection sourceSection, FrameSlot frameSlot) { - super(context, sourceSection); - this.frameSlot = frameSlot; - } - - public final FrameSlot getFrameSlot() { - return frameSlot; - } - - @Override - public FrameSlotNode copy() { - return (FrameSlotNode) super.copy(); - } - - protected final void setBoolean(Frame frame, boolean value) { - frame.setBoolean(frameSlot, value); - } - - protected final void setFixnum(Frame frame, int value) { - frame.setInt(frameSlot, value); - } - - protected final void setFloat(Frame frame, double value) { - frame.setDouble(frameSlot, value); - } - - protected final void setObject(Frame frame, Object value) { - frame.setObject(frameSlot, value); - } - - protected final boolean getBoolean(Frame frame) throws FrameSlotTypeException { - return frame.getBoolean(frameSlot); - } - - protected final int getFixnum(Frame frame) throws FrameSlotTypeException { - return frame.getInt(frameSlot); - } - - protected final double getFloat(Frame frame) throws FrameSlotTypeException { - return frame.getDouble(frameSlot); - } - - protected final Object getObject(Frame frame) { - try { - return frame.getObject(frameSlot); - } catch (FrameSlotTypeException e) { - throw new IllegalStateException(); - } - } - - protected final boolean isBooleanKind() { - return isKind(FrameSlotKind.Boolean); - } - - protected final boolean isFixnumKind() { - return isKind(FrameSlotKind.Int); - } - - protected final boolean isFloatKind() { - return isKind(FrameSlotKind.Double); - } - - protected final boolean isObjectKind() { - if (frameSlot.getKind() != FrameSlotKind.Object) { - CompilerDirectives.transferToInterpreter(); - frameSlot.setKind(FrameSlotKind.Object); - } - return true; - } - - private boolean isKind(FrameSlotKind kind) { - return frameSlot.getKind() == kind || initialSetKind(kind); - } - - private boolean initialSetKind(FrameSlotKind kind) { - if (frameSlot.getKind() == FrameSlotKind.Illegal) { - CompilerDirectives.transferToInterpreter(); - frameSlot.setKind(kind); - return true; - } - return false; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/locals/InitFlipFlopSlotNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/locals/InitFlipFlopSlotNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.methods.locals; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; - -public class InitFlipFlopSlotNode extends RubyNode { - - private final FrameSlot frameSlot; - - public InitFlipFlopSlotNode(RubyContext context, SourceSection sourceSection, FrameSlot frameSlot) { - super(context, sourceSection); - this.frameSlot = frameSlot; - } - - @Override - public void executeVoid(VirtualFrame frame) { - frame.setBoolean(frameSlot, false); - } - - @Override - public Object execute(VirtualFrame frame) { - executeVoid(frame); - return null; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/locals/LevelFlipFlopStateNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/locals/LevelFlipFlopStateNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.methods.locals; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.ruby.runtime.*; - -public class LevelFlipFlopStateNode extends FlipFlopStateNode { - - private final int level; - private final FrameSlot frameSlot; - - public LevelFlipFlopStateNode(SourceSection sourceSection, int level, FrameSlot frameSlot) { - super(sourceSection); - this.level = level; - this.frameSlot = frameSlot; - } - - @Override - public boolean getState(VirtualFrame frame) { - final MaterializedFrame levelFrame = RubyArguments.getDeclarationFrame(frame, level); - - try { - return levelFrame.getBoolean(frameSlot); - } catch (FrameSlotTypeException e) { - throw new IllegalStateException(); - } - } - - @Override - public void setState(VirtualFrame frame, boolean state) { - final MaterializedFrame levelFrame = RubyArguments.getDeclarationFrame(frame, level); - levelFrame.setBoolean(frameSlot, state); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/locals/LocalFlipFlopStateNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/locals/LocalFlipFlopStateNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.methods.locals; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; - -public class LocalFlipFlopStateNode extends FlipFlopStateNode { - - private final FrameSlot frameSlot; - - public LocalFlipFlopStateNode(SourceSection sourceSection, FrameSlot frameSlot) { - super(sourceSection); - this.frameSlot = frameSlot; - } - - @Override - public boolean getState(VirtualFrame frame) { - try { - return frame.getBoolean(frameSlot); - } catch (FrameSlotTypeException e) { - throw new IllegalStateException(); - } - } - - @Override - public void setState(VirtualFrame frame, boolean state) { - frame.setBoolean(frameSlot, state); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/locals/ReadLevelVariableNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/locals/ReadLevelVariableNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.methods.locals; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; - -public abstract class ReadLevelVariableNode extends FrameSlotNode implements ReadNode { - - private final int varLevel; - - public ReadLevelVariableNode(RubyContext context, SourceSection sourceSection, FrameSlot slot, int level) { - super(context, sourceSection, slot); - this.varLevel = level; - } - - public ReadLevelVariableNode(ReadLevelVariableNode prev) { - this(prev.getContext(), prev.getSourceSection(), prev.frameSlot, prev.varLevel); - } - - @Specialization(rewriteOn = {FrameSlotTypeException.class}) - public boolean doBoolean(VirtualFrame frame) throws FrameSlotTypeException { - MaterializedFrame levelFrame = RubyArguments.getDeclarationFrame(frame, varLevel); - return getBoolean(levelFrame); - } - - @Specialization(rewriteOn = {FrameSlotTypeException.class}) - public int doFixnum(VirtualFrame frame) throws FrameSlotTypeException { - MaterializedFrame levelFrame = RubyArguments.getDeclarationFrame(frame, varLevel); - return getFixnum(levelFrame); - } - - @Specialization(rewriteOn = {FrameSlotTypeException.class}) - public double doFloat(VirtualFrame frame) throws FrameSlotTypeException { - MaterializedFrame levelFrame = RubyArguments.getDeclarationFrame(frame, varLevel); - return getFloat(levelFrame); - } - - @Specialization - public Object doObject(VirtualFrame frame) { - MaterializedFrame levelFrame = RubyArguments.getDeclarationFrame(frame, varLevel); - return getObject(levelFrame); - } - - public int getVarLevel() { - return varLevel; - } - - @Override - public RubyNode makeWriteNode(RubyNode rhs) { - return WriteLevelVariableNodeFactory.create(getContext(), getSourceSection(), frameSlot, varLevel, rhs); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/locals/ReadLocalVariableNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/locals/ReadLocalVariableNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.methods.locals; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; - -public abstract class ReadLocalVariableNode extends FrameSlotNode implements ReadNode { - - public ReadLocalVariableNode(RubyContext context, SourceSection sourceSection, FrameSlot slot) { - super(context, sourceSection, slot); - } - - public ReadLocalVariableNode(ReadLocalVariableNode prev) { - this(prev.getContext(), prev.getSourceSection(), prev.frameSlot); - } - - @Specialization(rewriteOn = {FrameSlotTypeException.class}) - public boolean doBoolean(VirtualFrame frame) throws FrameSlotTypeException { - return getBoolean(frame); - } - - @Specialization(rewriteOn = {FrameSlotTypeException.class}) - public int doFixnum(VirtualFrame frame) throws FrameSlotTypeException { - return getFixnum(frame); - } - - @Specialization(rewriteOn = {FrameSlotTypeException.class}) - public double doFloat(VirtualFrame frame) throws FrameSlotTypeException { - return getFloat(frame); - } - - @Specialization - public Object doObject(VirtualFrame frame) { - return getObject(frame); - } - - @Override - public RubyNode makeWriteNode(RubyNode rhs) { - return WriteLocalVariableNodeFactory.create(getContext(), getSourceSection(), frameSlot, rhs); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/locals/WriteLevelVariableNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/locals/WriteLevelVariableNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.methods.locals; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; - -@NodeChild(value = "rhs", type = RubyNode.class) -public abstract class WriteLevelVariableNode extends FrameSlotNode implements WriteNode { - - private final int varLevel; - - public WriteLevelVariableNode(RubyContext context, SourceSection sourceSection, FrameSlot frameSlot, int level) { - super(context, sourceSection, frameSlot); - this.varLevel = level; - } - - protected WriteLevelVariableNode(WriteLevelVariableNode prev) { - this(prev.getContext(), prev.getSourceSection(), prev.frameSlot, prev.varLevel); - } - - @Specialization(guards = "isBooleanKind") - public boolean doBoolean(VirtualFrame frame, boolean value) { - MaterializedFrame levelFrame = RubyArguments.getDeclarationFrame(frame, varLevel); - setBoolean(levelFrame, value); - return value; - } - - @Specialization(guards = "isFixnumKind") - public int doFixnum(VirtualFrame frame, int value) { - MaterializedFrame levelFrame = RubyArguments.getDeclarationFrame(frame, varLevel); - setFixnum(levelFrame, value); - return value; - } - - @Specialization(guards = "isFloatKind") - public double doFloat(VirtualFrame frame, double value) { - MaterializedFrame levelFrame = RubyArguments.getDeclarationFrame(frame, varLevel); - setFloat(levelFrame, value); - return value; - } - - @Specialization(guards = "isObjectKind") - public Object doObject(VirtualFrame frame, Object value) { - MaterializedFrame levelFrame = RubyArguments.getDeclarationFrame(frame, varLevel); - setObject(levelFrame, value); - return value; - } - - @Override - public RubyNode makeReadNode() { - return ReadLevelVariableNodeFactory.create(getContext(), getSourceSection(), frameSlot, varLevel); - } -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/locals/WriteLocalVariableNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/methods/locals/WriteLocalVariableNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.methods.locals; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; - -@NodeChild(value = "rhs", type = RubyNode.class) -public abstract class WriteLocalVariableNode extends FrameSlotNode implements WriteNode { - - public WriteLocalVariableNode(RubyContext context, SourceSection sourceSection, FrameSlot frameSlot) { - super(context, sourceSection, frameSlot); - } - - protected WriteLocalVariableNode(WriteLocalVariableNode prev) { - this(prev.getContext(), prev.getSourceSection(), prev.frameSlot); - } - - @Specialization(guards = "isBooleanKind") - public boolean doFixnum(VirtualFrame frame, boolean value) { - setBoolean(frame, value); - return value; - } - - @Specialization(guards = "isFixnumKind") - public int doFixnum(VirtualFrame frame, int value) { - setFixnum(frame, value); - return value; - } - - @Specialization(guards = "isFloatKind") - public double doFloat(VirtualFrame frame, double value) { - setFloat(frame, value); - return value; - } - - @Specialization(guards = "isObjectKind") - public Object doObject(VirtualFrame frame, Object value) { - setObject(frame, value); - return value; - } - - @Override - public RubyNode makeReadNode() { - return ReadLocalVariableNodeFactory.create(getContext(), getSourceSection(), frameSlot); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/ClassNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/ClassNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.objects; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -/** - * Reads the class of an object. - */ -@NodeInfo(shortName = "class") -public class ClassNode extends RubyNode { - - @Child protected RubyNode child; - - public ClassNode(RubyContext context, SourceSection sourceSection, RubyNode child) { - super(context, sourceSection); - this.child = adoptChild(child); - } - - @Override - public Object execute(VirtualFrame frame) { - return ((RubyBasicObject) child.execute(frame)).getRubyClass(); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/DefineOrGetClassNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/DefineOrGetClassNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.objects; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.control.*; -import com.oracle.truffle.ruby.runtime.core.*; - -/** - * Define a new class, or get the existing one of the same name. - */ -public class DefineOrGetClassNode extends RubyNode { - - private final String name; - @Child protected RubyNode moduleDefinedIn; - @Child protected RubyNode superClass; - - public DefineOrGetClassNode(RubyContext context, SourceSection sourceSection, String name, RubyNode moduleDefinedIn, RubyNode superClass) { - super(context, sourceSection); - this.name = name; - this.moduleDefinedIn = adoptChild(moduleDefinedIn); - this.superClass = adoptChild(superClass); - } - - @Override - public Object execute(VirtualFrame frame) { - CompilerAsserts.neverPartOfCompilation(); - - final RubyContext context = getContext(); - - final RubyModule moduleDefinedInObject = (RubyModule) moduleDefinedIn.execute(frame); - - // Look for a current definition of the class, or create a new one - - final Object constantValue = moduleDefinedInObject.lookupConstant(name); - - RubyClass definingClass; - - if (constantValue == null) { - final Object self = frame.getArguments(RubyArguments.class).getSelf(); - - RubyModule parentModule; - - if (self instanceof RubyModule) { - parentModule = (RubyModule) self; - } else { - // Because it's top level, and so self is the magic main object - parentModule = null; - } - - final RubyClass superClassObject = (RubyClass) superClass.execute(frame); - - if (superClassObject instanceof RubyException.RubyExceptionClass) { - definingClass = new RubyException.RubyExceptionClass(superClassObject, name); - } else { - definingClass = new RubyClass(parentModule, superClassObject, name); - } - - moduleDefinedInObject.setConstant(name, definingClass); - moduleDefinedInObject.getSingletonClass().setConstant(name, definingClass); - - definingClass.getRubyClass().include(moduleDefinedInObject); - } else { - if (constantValue instanceof RubyClass) { - definingClass = (RubyClass) constantValue; - } else { - throw new RaiseException(context.getCoreLibrary().typeErrorIsNotA(constantValue.toString(), "class")); - } - } - - return definingClass; - } -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/DefineOrGetModuleNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/DefineOrGetModuleNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.objects; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.control.*; -import com.oracle.truffle.ruby.runtime.core.*; - -/** - * Define a new module, or get the existing one of the same name. - */ -public class DefineOrGetModuleNode extends RubyNode { - - private final String name; - @Child protected RubyNode moduleDefinedIn; - - public DefineOrGetModuleNode(RubyContext context, SourceSection sourceSection, String name, RubyNode moduleDefinedIn) { - super(context, sourceSection); - this.name = name; - this.moduleDefinedIn = adoptChild(moduleDefinedIn); - } - - @Override - public Object execute(VirtualFrame frame) { - CompilerAsserts.neverPartOfCompilation(); - - final RubyContext context = getContext(); - - final RubyModule moduleDefinedInObject = (RubyModule) moduleDefinedIn.execute(frame); - - // Look for a current definition of the module, or create a new one - - final Object constantValue = moduleDefinedInObject.lookupConstant(name); - - RubyModule definingModule; - - if (constantValue == null) { - final Object self = frame.getArguments(RubyArguments.class).getSelf(); - - RubyModule parentModule; - - if (self instanceof RubyModule) { - parentModule = (RubyModule) self; - } else { - // Because it's top level, and so self is the magic main object - parentModule = null; - } - - definingModule = new RubyModule(context.getCoreLibrary().getModuleClass(), parentModule, name); - moduleDefinedInObject.setConstant(name, definingModule); - moduleDefinedInObject.getSingletonClass().setConstant(name, definingModule); - } else { - if (constantValue instanceof RubyModule) { - definingModule = (RubyModule) constantValue; - } else { - throw new RaiseException(context.getCoreLibrary().typeErrorIsNotA(constantValue.toString(), "module")); - } - } - - return definingModule; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/OpenModuleNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/OpenModuleNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.objects; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.nodes.methods.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; - -/** - * Open a module and execute a method in it - probably to define new methods. - */ -public class OpenModuleNode extends RubyNode { - - @Child protected RubyNode definingModule; - @Child protected MethodDefinitionNode definitionMethod; - - public OpenModuleNode(RubyContext context, SourceSection sourceSection, RubyNode definingModule, MethodDefinitionNode definitionMethod) { - super(context, sourceSection); - this.definingModule = adoptChild(definingModule); - this.definitionMethod = adoptChild(definitionMethod); - } - - @Override - public Object execute(VirtualFrame frame) { - CompilerAsserts.neverPartOfCompilation(); - - // Call the definition method with the module as self - there's no return value - - final RubyModule module = (RubyModule) definingModule.execute(frame); - definitionMethod.executeMethod(frame).call(frame.pack(), module, null); - - return NilPlaceholder.INSTANCE; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/ReadClassVariableNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/ReadClassVariableNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.objects; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; - -@NodeInfo(shortName = "read-class-variable") -public class ReadClassVariableNode extends RubyNode { - - protected final String name; - @Child protected RubyNode module; - - public ReadClassVariableNode(RubyContext context, SourceSection sourceSection, String name, RubyNode module) { - super(context, sourceSection); - this.name = name; - this.module = adoptChild(module); - } - - @Override - public Object execute(VirtualFrame frame) { - final RubyObject object = (RubyObject) module.execute(frame); - - RubyModule moduleObject; - - // TODO(CS): this cannot be right - - if (object instanceof RubyModule) { - moduleObject = (RubyModule) object; - } else { - moduleObject = object.getRubyClass(); - } - - final Object value = moduleObject.lookupClassVariable(name); - - if (value == null) { - // TODO(CS): is this right? - return NilPlaceholder.INSTANCE; - } - - return value; - } - - @Override - public Object isDefined(VirtualFrame frame) { - final RubyContext context = getContext(); - - final RubyObject object = (RubyObject) module.execute(frame); - - RubyModule moduleObject; - - if (object instanceof RubyModule) { - moduleObject = (RubyModule) object; - } else { - moduleObject = object.getRubyClass(); - } - - final Object value = moduleObject.lookupClassVariable(name); - - if (value == null) { - return NilPlaceholder.INSTANCE; - } else { - return context.makeString("class variable"); - } - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/SelfNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/SelfNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.objects; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; - -@NodeInfo(shortName = "self") -public class SelfNode extends RubyNode { - - public SelfNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - @Override - public Object execute(VirtualFrame frame) { - final Object self = frame.getArguments(RubyArguments.class).getSelf(); - assert RubyContext.shouldObjectBeVisible(self); - return self; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/SingletonClassNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/SingletonClassNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.objects; - -import java.math.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -/** - * Reads the singleton (meta, eigen) class of an object. - */ -@NodeInfo(shortName = "singleton") -public class SingletonClassNode extends RubyNode { - - @Child protected RubyNode child; - - public SingletonClassNode(RubyContext context, SourceSection sourceSection, RubyNode child) { - super(context, sourceSection); - this.child = adoptChild(child); - } - - @Override - public Object execute(VirtualFrame frame) { - final Object childResult = child.execute(frame); - - final RubyContext context = getContext(); - - if (childResult instanceof NilPlaceholder) { - return context.getCoreLibrary().getNilClass(); - } else if (childResult instanceof BigInteger) { - // TODO(CS): this is problematic - do Bignums have singletons or not? - return context.getCoreLibrary().box(childResult).getSingletonClass(); - } else { - return ((RubyBasicObject) childResult).getSingletonClass(); - } - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/WriteClassVariableNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/WriteClassVariableNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.objects; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; - -@NodeInfo(shortName = "write-class-variable") -public class WriteClassVariableNode extends RubyNode { - - private final String name; - @Child protected RubyNode module; - @Child protected RubyNode rhs; - - public WriteClassVariableNode(RubyContext context, SourceSection sourceSection, String name, RubyNode module, RubyNode rhs) { - super(context, sourceSection); - this.name = name; - this.module = adoptChild(module); - this.rhs = adoptChild(rhs); - } - - @Override - public Object execute(VirtualFrame frame) { - // TODO(CS): can module ever not evaluate to a RubyModule? - - final RubyModule moduleObject = (RubyModule) module.execute(frame); - - final Object rhsValue = rhs.execute(frame); - - moduleObject.setClassVariable(name, rhsValue); - - return rhsValue; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/instancevariables/ReadFixnumInstanceVariableNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/instancevariables/ReadFixnumInstanceVariableNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.objects.instancevariables; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -@NodeInfo(shortName = "@Fixnum") -public class ReadFixnumInstanceVariableNode extends ReadSpecializedInstanceVariableNode { - - private final FixnumStorageLocation storageLocation; - - public ReadFixnumInstanceVariableNode(RubyContext context, SourceSection sourceSection, String name, RubyNode receiver, ObjectLayout objectLayout, FixnumStorageLocation storageLocation) { - super(context, sourceSection, name, receiver, objectLayout); - this.storageLocation = storageLocation; - } - - @Override - public int executeFixnum(VirtualFrame frame) throws UnexpectedResultException { - final RubyBasicObject receiverObject = (RubyBasicObject) receiver.execute(frame); - - final ObjectLayout receiverLayout = receiverObject.getObjectLayout(); - - final boolean condition = receiverLayout == objectLayout; - - if (condition) { - assert receiverLayout != null; - return storageLocation.readFixnum(receiverObject, condition); - } else { - CompilerDirectives.transferToInterpreter(); - replace(respecialize(receiverObject)); - throw new UnexpectedResultException(receiverObject.getInstanceVariable(name)); - } - } - - @Override - public Object execute(VirtualFrame frame) { - try { - return executeFixnum(frame); - } catch (UnexpectedResultException e) { - return e.getResult(); - } - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/instancevariables/ReadFloatInstanceVariableNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/instancevariables/ReadFloatInstanceVariableNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.objects.instancevariables; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -@NodeInfo(shortName = "@Float") -public class ReadFloatInstanceVariableNode extends ReadSpecializedInstanceVariableNode { - - private final FloatStorageLocation storageLocation; - - public ReadFloatInstanceVariableNode(RubyContext context, SourceSection sourceSection, String name, RubyNode receiver, ObjectLayout objectLayout, FloatStorageLocation storageLocation) { - super(context, sourceSection, name, receiver, objectLayout); - this.storageLocation = storageLocation; - } - - @Override - public double executeFloat(VirtualFrame frame) throws UnexpectedResultException { - final RubyBasicObject receiverObject = (RubyBasicObject) receiver.execute(frame); - - final ObjectLayout receiverLayout = receiverObject.getObjectLayout(); - - final boolean condition = receiverLayout == objectLayout; - - if (condition) { - assert receiverLayout != null; - return storageLocation.readFloat(receiverObject, condition); - } else { - CompilerDirectives.transferToInterpreter(); - replace(respecialize(receiverObject)); - throw new UnexpectedResultException(receiverObject.getInstanceVariable(name)); - } - } - - @Override - public Object execute(VirtualFrame frame) { - try { - return executeFloat(frame); - } catch (UnexpectedResultException e) { - return e.getResult(); - } - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/instancevariables/ReadInstanceVariableNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/instancevariables/ReadInstanceVariableNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.objects.instancevariables; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -public abstract class ReadInstanceVariableNode extends RubyNode implements ReadNode { - - protected final String name; - @Child protected RubyNode receiver; - - public ReadInstanceVariableNode(RubyContext context, SourceSection sourceSection, String name, RubyNode receiver) { - super(context, sourceSection); - this.name = name; - this.receiver = adoptChild(receiver); - } - - public ReadInstanceVariableNode respecialize(RubyBasicObject receiverObject) { - final StorageLocation storageLocation = receiverObject.getUpdatedObjectLayout().findStorageLocation(name); - - if (storageLocation == null) { - return new ReadMissingInstanceVariableNode(getSourceSection(), name, receiver, receiverObject.getObjectLayout(), getContext()); - } - - if (storageLocation instanceof FixnumStorageLocation) { - return new ReadFixnumInstanceVariableNode(getContext(), getSourceSection(), name, receiver, storageLocation.getObjectLayout(), (FixnumStorageLocation) storageLocation); - } else if (storageLocation instanceof FloatStorageLocation) { - return new ReadFloatInstanceVariableNode(getContext(), getSourceSection(), name, receiver, storageLocation.getObjectLayout(), (FloatStorageLocation) storageLocation); - } else { - return new ReadObjectInstanceVariableNode(getContext(), getSourceSection(), name, receiver, storageLocation.getObjectLayout(), (ObjectStorageLocation) storageLocation); - } - } - - public WriteInstanceVariableNode makeWriteNode(RubyNode rhs) { - return new UninitializedWriteInstanceVariableNode(getContext(), getEncapsulatingSourceSection(), name, (RubyNode) receiver.copy(), rhs); - } - - public String getName() { - return name; - } - - public RubyNode getReceiver() { - return receiver; - } - - @Override - public Object isDefined(VirtualFrame frame) { - final RubyContext context = getContext(); - - try { - final Object receiverObject = receiver.execute(frame); - final RubyBasicObject receiverRubyObject = context.getCoreLibrary().box(receiverObject); - - final ObjectLayout layout = receiverRubyObject.getObjectLayout(); - final StorageLocation storageLocation = layout.findStorageLocation(name); - - if (storageLocation.isSet(receiverRubyObject)) { - return context.makeString("instance-variable"); - } else { - return NilPlaceholder.INSTANCE; - } - } catch (Exception e) { - return NilPlaceholder.INSTANCE; - } - } -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/instancevariables/ReadMissingInstanceVariableNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/instancevariables/ReadMissingInstanceVariableNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.objects.instancevariables; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -@NodeInfo(shortName = "@missing") -public class ReadMissingInstanceVariableNode extends ReadSpecializedInstanceVariableNode { - - public ReadMissingInstanceVariableNode(SourceSection sourceSection, String name, RubyNode receiver, ObjectLayout objectLayout, RubyContext context) { - super(context, sourceSection, name, receiver, objectLayout); - } - - @Override - public Object execute(VirtualFrame frame) { - final RubyBasicObject receiverObject = (RubyBasicObject) receiver.execute(frame); - - if (!receiverObject.getObjectLayout().contains(objectLayout)) { - CompilerDirectives.transferToInterpreter(); - replace(respecialize(receiverObject)); - return receiverObject.getInstanceVariable(name); - } - - return NilPlaceholder.INSTANCE; - } -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/instancevariables/ReadObjectInstanceVariableNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/instancevariables/ReadObjectInstanceVariableNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.objects.instancevariables; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -@NodeInfo(shortName = "@Object") -public class ReadObjectInstanceVariableNode extends ReadSpecializedInstanceVariableNode { - - private final ObjectStorageLocation storageLocation; - - public ReadObjectInstanceVariableNode(RubyContext context, SourceSection sourceSection, String name, RubyNode receiver, ObjectLayout objectLayout, ObjectStorageLocation storageLocation) { - super(context, sourceSection, name, receiver, objectLayout); - this.storageLocation = storageLocation; - } - - @Override - public Object execute(VirtualFrame frame) { - final RubyBasicObject receiverObject = (RubyBasicObject) receiver.execute(frame); - - final ObjectLayout receiverLayout = receiverObject.getObjectLayout(); - - final boolean condition = receiverLayout == objectLayout; - - if (condition) { - assert receiverLayout != null; - return storageLocation.read(receiverObject, condition); - } else { - CompilerDirectives.transferToInterpreter(); - replace(respecialize(receiverObject)); - return receiverObject.getInstanceVariable(name); - } - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/instancevariables/ReadSpecializedInstanceVariableNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/instancevariables/ReadSpecializedInstanceVariableNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.objects.instancevariables; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -public abstract class ReadSpecializedInstanceVariableNode extends ReadInstanceVariableNode { - - protected final ObjectLayout objectLayout; - - public ReadSpecializedInstanceVariableNode(RubyContext context, SourceSection sourceSection, String name, RubyNode receiver, ObjectLayout objectLayout) { - super(context, sourceSection, name, receiver); - this.objectLayout = objectLayout; - } - - protected void respecialize() { - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/instancevariables/UninitializedReadInstanceVariableNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/instancevariables/UninitializedReadInstanceVariableNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.objects.instancevariables; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -@NodeInfo(shortName = "@uninit") -public class UninitializedReadInstanceVariableNode extends ReadInstanceVariableNode { - - public UninitializedReadInstanceVariableNode(RubyContext context, SourceSection sourceSection, String name, RubyNode receiver) { - super(context, sourceSection, name, receiver); - } - - @Override - public Object execute(VirtualFrame frame) { - CompilerDirectives.transferToInterpreter(); - final RubyBasicObject receiverObject = (RubyBasicObject) receiver.execute(frame); - replace(respecialize(receiverObject)); - return receiverObject.getInstanceVariable(name); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/instancevariables/UninitializedWriteInstanceVariableNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/instancevariables/UninitializedWriteInstanceVariableNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.objects.instancevariables; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -@NodeInfo(shortName = "@uninit=") -public class UninitializedWriteInstanceVariableNode extends WriteInstanceVariableNode { - - public UninitializedWriteInstanceVariableNode(RubyContext context, SourceSection sourceSection, String name, RubyNode receiver, RubyNode rhs) { - super(context, sourceSection, name, receiver, rhs); - } - - @Override - public Object execute(VirtualFrame frame) { - CompilerDirectives.transferToInterpreter(); - final RubyBasicObject receiverObject = (RubyBasicObject) receiver.execute(frame); - final Object value = rhs.execute(frame); - receiverObject.setInstanceVariable(name, value); - replace(respecialize(receiverObject)); - return value; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/instancevariables/WriteFixnumInstanceVariableNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/instancevariables/WriteFixnumInstanceVariableNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.objects.instancevariables; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -@NodeInfo(shortName = "@Fixnum=") -public class WriteFixnumInstanceVariableNode extends WriteSpecializedInstanceVariableNode { - - private final FixnumStorageLocation storageLocation; - - public WriteFixnumInstanceVariableNode(RubyContext context, SourceSection sourceSection, String name, RubyNode receiver, RubyNode rhs, ObjectLayout objectLayout, - FixnumStorageLocation storageLocation) { - super(context, sourceSection, name, receiver, rhs, objectLayout); - this.storageLocation = storageLocation; - } - - @Override - public int executeFixnum(VirtualFrame frame) throws UnexpectedResultException { - final RubyBasicObject receiverObject = (RubyBasicObject) receiver.execute(frame); - - int value; - - try { - value = rhs.executeFixnum(frame); - } catch (UnexpectedResultException e) { - receiverObject.setInstanceVariable(name, e.getResult()); - replace(respecialize(receiverObject)); - throw e; - } - - final ObjectLayout receiverLayout = receiverObject.getObjectLayout(); - - if (receiverLayout != objectLayout) { - CompilerDirectives.transferToInterpreter(); - receiverObject.setInstanceVariable(name, value); - replace(respecialize(receiverObject)); - return value; - } - - assert receiverLayout != null; - - storageLocation.writeFixnum(receiverObject, value); - return value; - } - - @Override - public Object execute(VirtualFrame frame) { - try { - return executeFixnum(frame); - } catch (UnexpectedResultException e) { - return e.getResult(); - } - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/instancevariables/WriteFloatInstanceVariableNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/instancevariables/WriteFloatInstanceVariableNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.objects.instancevariables; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -@NodeInfo(shortName = "@Float=") -public class WriteFloatInstanceVariableNode extends WriteSpecializedInstanceVariableNode { - - private final FloatStorageLocation storageLocation; - - public WriteFloatInstanceVariableNode(RubyContext context, SourceSection sourceSection, String name, RubyNode receiver, RubyNode rhs, ObjectLayout objectLayout, - FloatStorageLocation storageLocation) { - super(context, sourceSection, name, receiver, rhs, objectLayout); - this.storageLocation = storageLocation; - } - - @Override - public double executeFloat(VirtualFrame frame) throws UnexpectedResultException { - final RubyBasicObject receiverObject = (RubyBasicObject) receiver.execute(frame); - - double value; - - try { - value = rhs.executeFloat(frame); - } catch (UnexpectedResultException e) { - receiverObject.setInstanceVariable(name, e.getResult()); - replace(respecialize(receiverObject)); - throw e; - } - - final ObjectLayout receiverLayout = receiverObject.getObjectLayout(); - - if (receiverLayout != objectLayout) { - CompilerDirectives.transferToInterpreter(); - receiverObject.setInstanceVariable(name, value); - replace(respecialize(receiverObject)); - return value; - } - - assert receiverLayout != null; - - storageLocation.writeFloat(receiverObject, value); - return value; - } - - @Override - public Object execute(VirtualFrame frame) { - try { - return executeFloat(frame); - } catch (UnexpectedResultException e) { - return e.getResult(); - } - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/instancevariables/WriteInstanceVariableNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/instancevariables/WriteInstanceVariableNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.objects.instancevariables; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -public abstract class WriteInstanceVariableNode extends RubyNode implements WriteNode { - - protected final String name; - @Child protected RubyNode receiver; - @Child protected RubyNode rhs; - - public WriteInstanceVariableNode(RubyContext context, SourceSection sourceSection, String name, RubyNode receiver, RubyNode rhs) { - super(context, sourceSection); - this.name = name; - this.receiver = adoptChild(receiver); - this.rhs = adoptChild(rhs); - } - - public WriteInstanceVariableNode respecialize(RubyBasicObject receiverObject) { - StorageLocation storageLocation = receiverObject.getObjectLayout().findStorageLocation(name); - - if (storageLocation == null) { - throw new RuntimeException("Storage location should be found at this point"); - } - - if (storageLocation instanceof FixnumStorageLocation) { - return new WriteFixnumInstanceVariableNode(getContext(), getSourceSection(), name, receiver, rhs, storageLocation.getObjectLayout(), (FixnumStorageLocation) storageLocation); - } else if (storageLocation instanceof FloatStorageLocation) { - return new WriteFloatInstanceVariableNode(getContext(), getSourceSection(), name, receiver, rhs, storageLocation.getObjectLayout(), (FloatStorageLocation) storageLocation); - } else { - return new WriteObjectInstanceVariableNode(getContext(), getSourceSection(), name, receiver, rhs, storageLocation.getObjectLayout(), (ObjectStorageLocation) storageLocation); - } - } - - @Override - public ReadInstanceVariableNode makeReadNode() { - return new UninitializedReadInstanceVariableNode(getContext(), getEncapsulatingSourceSection(), name, (RubyNode) receiver.copy()); - } - - public String getName() { - return name; - } - - public RubyNode getReceiver() { - return receiver; - } - - public RubyNode getRHS() { - return rhs; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/instancevariables/WriteObjectInstanceVariableNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/instancevariables/WriteObjectInstanceVariableNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.objects.instancevariables; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -@NodeInfo(shortName = "@Object=") -public class WriteObjectInstanceVariableNode extends WriteSpecializedInstanceVariableNode { - - private final ObjectStorageLocation storageLocation; - - public WriteObjectInstanceVariableNode(RubyContext context, SourceSection sourceSection, String name, RubyNode receiver, RubyNode rhs, ObjectLayout objectLayout, - ObjectStorageLocation storageLocation) { - super(context, sourceSection, name, receiver, rhs, objectLayout); - this.storageLocation = storageLocation; - } - - @Override - public Object execute(VirtualFrame frame) { - final RubyBasicObject receiverObject = (RubyBasicObject) receiver.execute(frame); - final Object value = rhs.execute(frame); - - final ObjectLayout receiverLayout = receiverObject.getObjectLayout(); - - if (receiverLayout != objectLayout) { - CompilerDirectives.transferToInterpreter(); - receiverObject.setInstanceVariable(name, value); - replace(respecialize(receiverObject)); - return value; - } - - assert receiverLayout != null; - - storageLocation.write(receiverObject, value); - return value; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/instancevariables/WriteSpecializedInstanceVariableNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/objects/instancevariables/WriteSpecializedInstanceVariableNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.objects.instancevariables; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -public abstract class WriteSpecializedInstanceVariableNode extends WriteInstanceVariableNode { - - protected final ObjectLayout objectLayout; - - public WriteSpecializedInstanceVariableNode(RubyContext context, SourceSection sourceSection, String name, RubyNode receiver, RubyNode rhs, ObjectLayout objectLayout) { - super(context, sourceSection, name, receiver, rhs); - this.objectLayout = objectLayout; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/yield/GeneralYieldDispatchNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/yield/GeneralYieldDispatchNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.yield; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; - -/** - * A yield dispatch node that just calls {@link RubyProc#call} as normal. - */ -public class GeneralYieldDispatchNode extends YieldDispatchNode { - - public GeneralYieldDispatchNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - @Override - public Object dispatch(VirtualFrame frame, RubyProc block, Object[] argumentsObjects) { - return block.call(frame.pack(), argumentsObjects); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/yield/InlinedYieldDispatchNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/yield/InlinedYieldDispatchNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.yield; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; - -/** - * Dispatch to a known method which has been inlined. - */ -public class InlinedYieldDispatchNode extends YieldDispatchNode { - - private final RubyRootNode pristineRootNode; - - private final FrameDescriptor frameDescriptor; - private final RubyRootNode rootNode; - - public InlinedYieldDispatchNode(RubyContext context, SourceSection sourceSection, InlinableMethodImplementation method) { - super(context, sourceSection); - pristineRootNode = method.getPristineRootNode(); - frameDescriptor = method.getFrameDescriptor(); - rootNode = method.getCloneOfPristineRootNode(); - } - - @Override - public Object dispatch(VirtualFrame frame, RubyProc block, Object[] argumentsObjects) { - /* - * We're inlining based on the root node used, checking that root node still matches, and - * then taking the materialized frame from the block we actually got. We can't look for - * RubyMethod or RubyProc, because they're allocated for each call passing a block. - */ - - if (!(block.getMethod().getImplementation() instanceof InlinableMethodImplementation) || - ((InlinableMethodImplementation) block.getMethod().getImplementation()).getPristineRootNode() != pristineRootNode) { - CompilerDirectives.transferToInterpreter(); - - // TODO(CS): at the moment we just go back to uninit, which may cause loops - - final UninitializedYieldDispatchNode dispatch = new UninitializedYieldDispatchNode(getContext(), getSourceSection()); - replace(dispatch); - return dispatch.dispatch(frame, block, argumentsObjects); - } - - final InlinableMethodImplementation implementation = (InlinableMethodImplementation) block.getMethod().getImplementation(); - - final RubyArguments arguments = new RubyArguments(implementation.getDeclarationFrame(), block.getSelf(), block.getBlock(), argumentsObjects); - final VirtualFrame inlinedFrame = Truffle.getRuntime().createVirtualFrame(frame.pack(), arguments, frameDescriptor); - return rootNode.execute(inlinedFrame); - } -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/yield/UninitializedYieldDispatchNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/yield/UninitializedYieldDispatchNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.yield; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.nodes.call.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.methods.*; - -/** - * An uninitialized node in the yield dispatch chain. - */ -public class UninitializedYieldDispatchNode extends YieldDispatchNode { - - public UninitializedYieldDispatchNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - @Override - public Object dispatch(VirtualFrame frame, RubyProc block, Object[] argumentsObjects) { - CompilerDirectives.transferToInterpreter(); - - final MethodImplementation implementation = block.getMethod().getImplementation(); - - if (implementation instanceof InlinableMethodImplementation && InlineHeuristic.shouldInlineYield((InlinableMethodImplementation) implementation)) { - final InlinedYieldDispatchNode dispatch = new InlinedYieldDispatchNode(getContext(), getSourceSection(), (InlinableMethodImplementation) implementation); - replace(dispatch); - return dispatch.dispatch(frame, block, argumentsObjects); - } else { - final GeneralYieldDispatchNode dispatch = new GeneralYieldDispatchNode(getContext(), getSourceSection()); - replace(dispatch); - return dispatch.dispatch(frame, block, argumentsObjects); - } - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/yield/YieldDispatchNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/yield/YieldDispatchNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.yield; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; - -/** - * A node in the yield dispatch chain. - */ -public abstract class YieldDispatchNode extends Node { - - private final RubyContext context; - - public YieldDispatchNode(RubyContext context, SourceSection sourceSection) { - super(sourceSection); - - assert context != null; - assert sourceSection != null; - - this.context = context; - } - - public abstract Object dispatch(VirtualFrame frame, RubyProc block, Object[] argumentsObjects); - - public RubyContext getContext() { - return context; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/yield/YieldNode.java --- a/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/yield/YieldNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.nodes.yield; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; - -/** - * Yield to the current block. - */ -@NodeInfo(shortName = "yield") -public class YieldNode extends RubyNode { - - @Children protected final RubyNode[] arguments; - @Child protected YieldDispatchNode dispatch; - - public YieldNode(RubyContext context, SourceSection sourceSection, RubyNode[] arguments) { - super(context, sourceSection); - this.arguments = adoptChildren(arguments); - dispatch = adoptChild(new UninitializedYieldDispatchNode(getContext(), getSourceSection())); - } - - @ExplodeLoop - @Override - public final Object execute(VirtualFrame frame) { - final Object[] argumentsObjects = new Object[arguments.length]; - - for (int i = 0; i < arguments.length; i++) { - argumentsObjects[i] = arguments[i].execute(frame); - } - - final RubyProc block = frame.getArguments(RubyArguments.class).getBlock(); - - if (block == null) { - CompilerDirectives.transferToInterpreter(); - // TODO(CS): convert to the proper Ruby exception - throw new RuntimeException("No block to yield to"); - } - - return dispatch.dispatch(frame, block, argumentsObjects); - } - - @Override - public Object isDefined(VirtualFrame frame) { - final RubyArguments args = frame.getArguments(RubyArguments.class); - - if (args.getBlock() == null) { - return NilPlaceholder.INSTANCE; - } else { - return getContext().makeString("yield"); - } - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/DeadNode.java --- a/graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/DeadNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.parser; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.*; - -/** - * Dead nodes are removed wherever they are found during translation. They fill in for some missing - * nodes when we're processing the AST. - */ -public class DeadNode extends RubyNode { - - public DeadNode(RubyContext context, SourceSection sourceSection) { - super(context, sourceSection); - } - - @Override - public Object execute(VirtualFrame frame) { - throw new UnsupportedOperationException("Dead nodes should have been pruned before execution starts"); - } -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/DefaultRubyNodeInstrumenter.java --- a/graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/DefaultRubyNodeInstrumenter.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.parser; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.nodes.instrument.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.nodes.debug.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.debug.*; -import com.oracle.truffle.ruby.runtime.methods.*; - -/** - * Utility for instrumenting Ruby AST nodes to support the language's built-in tracing - * facility. It ignores nodes other than {@linkplain NodePhylum#STATEMENT statements}. - */ -final class DefaultRubyNodeInstrumenter implements RubyNodeInstrumenter { - - public DefaultRubyNodeInstrumenter() { - } - - public RubyNode instrumentAsStatement(RubyNode node) { - assert node != null; - - final RubyContext context = node.getContext(); - - RubyProxyNode proxy; - - if (node instanceof RubyProxyNode) { - proxy = (RubyProxyNode) node; - } else { - proxy = new RubyProxyNode(node.getContext(), node); - proxy.markAs(NodePhylum.STATEMENT); - proxy.clearSourceSection(); - proxy.assignSourceSection(node.getSourceSection()); - } - - if (context.getConfiguration().getTrace()) { - proxy.getProbeChain().appendProbe(new RubyTraceProbe(context)); - } - - if (context.getConfiguration().getDebug()) { - final SourceSection sourceSection = proxy.getChild().getSourceSection(); - final SourceLineLocation sourceLine = new SourceLineLocation(sourceSection.getSource(), sourceSection.getStartLine()); - proxy.getProbeChain().appendProbe(new InactiveLineDebugProbe(context, sourceLine, context.getRubyDebugManager().getAssumption(sourceLine))); - } - - return proxy; - } - - public RubyNode instrumentAsCall(RubyNode node, String callName) { - return node; - } - - public RubyNode instrumentAsLocalAssignment(RubyNode node, UniqueMethodIdentifier methodIdentifier, String localName) { - assert node != null; - - final RubyContext context = node.getContext(); - - RubyProxyNode proxy; - - if (node instanceof RubyProxyNode) { - proxy = (RubyProxyNode) node; - } else { - proxy = new RubyProxyNode(node.getContext(), node); - proxy.markAs(NodePhylum.STATEMENT); - proxy.clearSourceSection(); - proxy.assignSourceSection(node.getSourceSection()); - } - - if (context.getConfiguration().getDebug()) { - final MethodLocal methodLocal = new MethodLocal(methodIdentifier, localName); - proxy.getProbeChain().appendProbe(new InactiveLocalDebugProbe(context, methodLocal, context.getRubyDebugManager().getAssumption(methodLocal))); - } - - return proxy; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/JRubyParser.java --- a/graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/JRubyParser.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,198 +0,0 @@ -/* - * Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.parser; - -import java.io.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.nodes.control.*; -import com.oracle.truffle.ruby.nodes.literal.*; -import com.oracle.truffle.ruby.nodes.methods.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.control.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.methods.*; - -public class JRubyParser implements RubyParser { - - private long nextReturnID = 0; - - private final RubyNodeInstrumenter instrumenter; - - public JRubyParser() { - this(new DefaultRubyNodeInstrumenter()); - } - - public JRubyParser(RubyNodeInstrumenter instrumenter) { - assert instrumenter != null; - this.instrumenter = instrumenter; - } - - @Override - public RubyParserResult parse(RubyContext context, Source source, ParserContext parserContext, MaterializedFrame parentFrame) { - - // Set up the JRuby parser - - final org.jrubyparser.Parser parser = new org.jrubyparser.Parser(); - - // TODO(cs) should this get a new unique method identifier or not? - final TranslatorEnvironment environment = new TranslatorEnvironment(context, environmentForFrame(context, parentFrame), this, allocateReturnID(), true, true, new UniqueMethodIdentifier()); - - // All parsing contexts have a visibility slot at their top level - - environment.addMethodDeclarationSlots(); - - final org.jrubyparser.LocalStaticScope staticScope = new org.jrubyparser.LocalStaticScope(null); - - if (parentFrame != null) { - /* - * Note that jruby-parser will be mistaken about how deep the existing variables are, - * but that doesn't matter as we look them up ourselves after being told their in some - * parent scope. - */ - - MaterializedFrame frame = parentFrame; - - while (frame != null) { - for (FrameSlot slot : frame.getFrameDescriptor().getSlots()) { - if (slot.getIdentifier() instanceof String) { - final String name = (String) slot.getIdentifier(); - if (staticScope.exists(name) == -1) { - staticScope.assign(null, name, null); - } - } - } - - frame = frame.getArguments(RubyArguments.class).getDeclarationFrame(); - } - } - - final org.jrubyparser.parser.ParserConfiguration parserConfiguration = new org.jrubyparser.parser.ParserConfiguration(0, org.jrubyparser.CompatVersion.RUBY2_0, staticScope); - - // Parse to the JRuby AST - - org.jrubyparser.ast.RootNode node; - - try { - node = (org.jrubyparser.ast.RootNode) parser.parse(source.getName(), new StringReader(source.getCode()), parserConfiguration); - } catch (UnsupportedOperationException | org.jrubyparser.lexer.SyntaxException e) { - String message = e.getMessage(); - - if (message == null) { - message = "(no message)"; - } - - throw new RaiseException(new RubyException(context.getCoreLibrary().getSyntaxErrorClass(), message)); - } - - if (context.getConfiguration().getPrintParseTree()) { - System.err.println(node); - } - - // Translate to Ruby Truffle nodes - - final Translator translator; - - if (parserContext == RubyParser.ParserContext.MODULE) { - translator = new ModuleTranslator(context, null, environment, source); - } else { - translator = new Translator(context, null, environment, source); - } - - RubyNode truffleNode; - - final DebugManager debugManager = context.getDebugManager(); - try { - if (debugManager != null) { - debugManager.notifyStartLoading(source); - } - - if (node.getBody() == null) { - truffleNode = new NilNode(context, null); - } else { - truffleNode = (RubyNode) node.getBody().accept(translator); - } - - // Load flip-flop states - - if (environment.getFlipFlopStates().size() > 0) { - truffleNode = new SequenceNode(context, truffleNode.getSourceSection(), translator.initFlipFlopStates(truffleNode.getSourceSection()), truffleNode); - } - - // Catch next - - truffleNode = new CatchNextNode(context, truffleNode.getSourceSection(), truffleNode); - - // Catch return - - truffleNode = new CatchReturnAsErrorNode(context, truffleNode.getSourceSection(), truffleNode); - - // Shell result - - if (parserContext == RubyParser.ParserContext.SHELL) { - truffleNode = new ShellResultNode(context, truffleNode.getSourceSection(), truffleNode); - } - - // Root Node - - String indicativeName; - - switch (parserContext) { - case TOP_LEVEL: - indicativeName = "(main)"; - break; - case SHELL: - indicativeName = "(shell)"; - break; - case MODULE: - indicativeName = "(module)"; - break; - default: - throw new UnsupportedOperationException(); - } - - final RootNode root = new RubyRootNode(truffleNode.getSourceSection(), environment.getFrameDescriptor(), indicativeName, truffleNode); - - // Return the root and the frame descriptor - return new RubyParserResult(root); - } finally { - if (debugManager != null) { - debugManager.notifyFinishedLoading(source); - } - } - } - - public long allocateReturnID() { - if (nextReturnID == Long.MAX_VALUE) { - throw new RuntimeException("Return IDs exhausted"); - } - - final long allocated = nextReturnID; - nextReturnID++; - return allocated; - } - - public RubyNodeInstrumenter getNodeInstrumenter() { - return instrumenter; - } - - private TranslatorEnvironment environmentForFrame(RubyContext context, MaterializedFrame frame) { - if (frame == null) { - return null; - } else { - final MaterializedFrame parent = frame.getArguments(RubyArguments.class).getDeclarationFrame(); - return new TranslatorEnvironment(context, environmentForFrame(context, parent), frame.getFrameDescriptor(), this, allocateReturnID(), true, true, new UniqueMethodIdentifier()); - } - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/MethodTranslator.java --- a/graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/MethodTranslator.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,338 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.parser; - -import java.util.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.nodes.call.*; -import com.oracle.truffle.ruby.nodes.control.*; -import com.oracle.truffle.ruby.nodes.literal.*; -import com.oracle.truffle.ruby.nodes.methods.*; -import com.oracle.truffle.ruby.nodes.methods.arguments.*; -import com.oracle.truffle.ruby.nodes.methods.locals.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.methods.*; - -class MethodTranslator extends Translator { - - private boolean isBlock; - - public MethodTranslator(RubyContext context, Translator parent, TranslatorEnvironment environment, boolean isBlock, Source source) { - super(context, parent, environment, source); - this.isBlock = isBlock; - } - - public MethodDefinitionNode compileFunctionNode(SourceSection sourceSection, String methodName, org.jrubyparser.ast.ArgsNode argsNode, org.jrubyparser.ast.Node bodyNode) { - environment.setMethodName(methodName); - - final Arity arity = findParameters(argsNode); - - RubyNode body; - - if (bodyNode != null) { - body = (RubyNode) bodyNode.accept(this); - } else { - body = new NilNode(context, sourceSection); - } - - body = loadArgumentsIntoLocals(arity, body); - - if (environment.getFlipFlopStates().size() > 0) { - body = new SequenceNode(context, sourceSection, initFlipFlopStates(sourceSection), body); - } - - if (isBlock) { - body = new CatchNextNode(context, sourceSection, body); - } else { - body = new CatchReturnNode(context, sourceSection, body, environment.getReturnID()); - body = new CatchNextNode(context, sourceSection, body); - } - - final RubyRootNode pristineRootNode = new RubyRootNode(sourceSection, environment.getFrameDescriptor(), methodName, body); - - final CallTarget callTarget = Truffle.getRuntime().createCallTarget(NodeUtil.cloneNode(pristineRootNode)); - - if (isBlock) { - return new BlockDefinitionNode(context, sourceSection, methodName, environment.getUniqueMethodIdentifier(), environment.getFrameDescriptor(), environment.needsDeclarationFrame(), - pristineRootNode, callTarget); - } else { - return new MethodDefinitionNode(context, sourceSection, methodName, environment.getUniqueMethodIdentifier(), environment.getFrameDescriptor(), environment.needsDeclarationFrame(), - pristineRootNode, callTarget); - } - } - - private RubyNode loadArgumentsIntoLocals(Arity arity, RubyNode body) { - final SourceSection sourceSection = body.getEncapsulatingSourceSection(); - - final List loadIndividualArgumentsNodes = new ArrayList<>(); - - if (!isBlock) { - loadIndividualArgumentsNodes.add(new CheckArityNode(context, sourceSection, arity)); - } - - final int preCount = environment.getPreParameters().size(); - final int postCount = environment.getPostParameters().size(); - - for (int n = 0; n < environment.getPreParameters().size(); n++) { - final FrameSlot param = environment.getPreParameters().get(n); - - // ReadPre reads from the start of the arguments array - - final ReadPreArgumentNode readArgumentNode = new ReadPreArgumentNode(context, sourceSection, n, false); - - final WriteLocalVariableNode writeLocal = WriteLocalVariableNodeFactory.create(context, sourceSection, param, readArgumentNode); - - loadIndividualArgumentsNodes.add(writeLocal); - } - - for (int n = 0; n < environment.getOptionalParameters().size(); n++) { - final FrameSlot param = environment.getOptionalParameters().get(n); - final RubyNode defaultValue = environment.getOptionalParametersDefaultValues().get(param); - - /* - * ReadOptional reads from the start of the arguments array, as long as it is long - * enough, else uses the default value (which may use locals with arguments just loaded, - * either from pre or preceding optionals). - */ - - final ReadOptionalArgumentNode readArgumentNode = new ReadOptionalArgumentNode(context, body.getEncapsulatingSourceSection(), preCount + n, preCount + postCount + n + 1, - (RubyNode) defaultValue.copy()); - - final WriteLocalVariableNode writeLocal = WriteLocalVariableNodeFactory.create(context, sourceSection, param, readArgumentNode); - - loadIndividualArgumentsNodes.add(writeLocal); - } - - for (int n = 0; n < environment.getPostParameters().size(); n++) { - final FrameSlot param = environment.getPostParameters().get(n); - - // ReadPost reads from the end of the arguments array - - final ReadPostArgumentNode readArgumentNode = new ReadPostArgumentNode(context, sourceSection, postCount - n - 1); - - final WriteLocalVariableNode writeLocal = WriteLocalVariableNodeFactory.create(context, sourceSection, param, readArgumentNode); - - loadIndividualArgumentsNodes.add(writeLocal); - } - - if (environment.getRestParameter() != null) { - /* - * TODO(cs): this assumes there are no optionals and therefore also no posts, which may - * not be a valid assumption. - */ - - if (postCount != 0) { - context.implementationMessage("post arguments as well as a rest argument - they will conflict"); - } - - final ReadRestArgumentNode readArgumentNode = new ReadRestArgumentNode(context, sourceSection, preCount); - - final WriteLocalVariableNode writeLocal = WriteLocalVariableNodeFactory.create(context, sourceSection, environment.getRestParameter(), readArgumentNode); - - loadIndividualArgumentsNodes.add(writeLocal); - } - - if (environment.getBlockParameter() != null) { - final FrameSlot param = environment.getBlockParameter(); - - final ReadBlockArgumentNode readArgumentNode = new ReadBlockArgumentNode(context, sourceSection, false); - - final WriteLocalVariableNode writeLocal = WriteLocalVariableNodeFactory.create(context, sourceSection, param, readArgumentNode); - - loadIndividualArgumentsNodes.add(writeLocal); - } - - final RubyNode loadIndividualArguments = new SequenceNode(context, sourceSection, loadIndividualArgumentsNodes.toArray(new RubyNode[loadIndividualArgumentsNodes.size()])); - - final RubyNode noSwitch = new SequenceNode(context, body.getSourceSection(), loadIndividualArguments, body); - - if (!isBlock) { - return noSwitch; - } - - /* - * See the test testBlockArgumentsDestructure for a motivation for this. See - * BlockDestructureSwitchNode for how it works. - */ - - if (preCount + postCount == 1 && environment.getOptionalParameters().size() == 0) { - return noSwitch; - } - - final List destructureLoadArgumentsNodes = new ArrayList<>(); - - for (int n = 0; n < environment.getPreParameters().size(); n++) { - final FrameSlot param = environment.getPreParameters().get(n); - - final ReadDestructureArgumentNode readArgumentNode = new ReadDestructureArgumentNode(context, sourceSection, n); - - final WriteLocalVariableNode writeLocal = WriteLocalVariableNodeFactory.create(context, sourceSection, param, readArgumentNode); - - destructureLoadArgumentsNodes.add(writeLocal); - } - - final RubyNode destructureLoadArguments = new SequenceNode(context, body.getSourceSection(), destructureLoadArgumentsNodes.toArray(new RubyNode[destructureLoadArgumentsNodes.size()])); - - return new BlockDestructureSwitchNode(context, body.getEncapsulatingSourceSection(), loadIndividualArguments, destructureLoadArguments, body); - - } - - private Arity findParameters(org.jrubyparser.ast.ArgsNode args) { - if (args == null) { - return Arity.NO_ARGS; - } - - final SourceSection sourceSection = translate(args.getPosition()); - - if (args.getPre() != null) { - for (org.jrubyparser.ast.Node arg : args.getPre().childNodes()) { - if (arg instanceof org.jrubyparser.ast.ArgumentNode) { - final org.jrubyparser.ast.ArgumentNode argNode = (org.jrubyparser.ast.ArgumentNode) arg; - environment.getPreParameters().add(environment.declareVar(argNode.getName())); - } else if (arg instanceof org.jrubyparser.ast.MultipleAsgnNode) { - /* - * TODO(cs): I don't know how to handle this yet, so I just do my best to get - * the names out and define them so the rest of the parser succeeds. - */ - - context.implementationMessage("only extracting names from multiple assignment in arguments"); - - final org.jrubyparser.ast.MultipleAsgnNode multAsgn = (org.jrubyparser.ast.MultipleAsgnNode) arg; - - final List names = new ArrayList<>(); - getNamesFromMultipleAssignment(multAsgn, names); - - for (String name : names) { - environment.getPreParameters().add(environment.declareVar(name)); - } - } - } - } - - // The JRuby parser expresses optional arguments as a block of local assignments - - /* - * Note that default values for optional params can refer to the actual value of previous - * args, so be careful with the order of args here and in loadArgumentsIntoLocals. - */ - - if (args.getOptional() != null) { - for (org.jrubyparser.ast.Node arg : args.getOptional().childNodes()) { - final org.jrubyparser.ast.OptArgNode optArgNode = (org.jrubyparser.ast.OptArgNode) arg; - - String name; - org.jrubyparser.ast.Node valueNode; - - if (optArgNode.getValue() instanceof org.jrubyparser.ast.LocalAsgnNode) { - final org.jrubyparser.ast.LocalAsgnNode optLocalAsgn = (org.jrubyparser.ast.LocalAsgnNode) optArgNode.getValue(); - name = optLocalAsgn.getName(); - valueNode = optLocalAsgn.getValue(); - } else if (optArgNode.getValue() instanceof org.jrubyparser.ast.DAsgnNode) { - final org.jrubyparser.ast.DAsgnNode optLocalAsgn = (org.jrubyparser.ast.DAsgnNode) optArgNode.getValue(); - name = optLocalAsgn.getName(); - valueNode = optLocalAsgn.getValue(); - } else { - throw new UnsupportedOperationException(optArgNode.getValue().getClass().getName()); - } - - RubyNode paramDefaultValue; - - if (valueNode == null) { - paramDefaultValue = new NilNode(context, sourceSection); - } else { - paramDefaultValue = (RubyNode) valueNode.accept(this); - } - - final FrameSlot frameSlot = environment.declareVar(name); - environment.getOptionalParameters().add(frameSlot); - environment.getOptionalParametersDefaultValues().put(frameSlot, paramDefaultValue); - } - } - - if (args.getPost() != null) { - for (org.jrubyparser.ast.Node arg : args.getPost().childNodes()) { - final org.jrubyparser.ast.ArgumentNode argNode = (org.jrubyparser.ast.ArgumentNode) arg; - environment.getPostParameters().add(environment.declareVar(argNode.getName())); - } - } - - if (args.getRest() != null) { - final org.jrubyparser.ast.RestArgNode rest = (org.jrubyparser.ast.RestArgNode) args.getRest(); - environment.setRestParameter(environment.declareVar(rest.getName())); - } - - if (args.getBlock() != null) { - final org.jrubyparser.ast.BlockArgNode blockArgNode = args.getBlock(); - final FrameSlot frameSlot = environment.declareVar(blockArgNode.getName()); - environment.setBlockParameter(frameSlot); - } - - final int minimum = environment.getPreParameters().size() + environment.getPostParameters().size(); - - int maximum = minimum + environment.getOptionalParameters().size(); - - if (args.getRest() != null) { - maximum = Arity.NO_MAXIMUM; - } - - return new Arity(minimum, maximum); - } - - private void getNamesFromMultipleAssignment(org.jrubyparser.ast.MultipleAsgnNode multAsgn, List names) { - for (org.jrubyparser.ast.Node a : multAsgn.getPre().childNodes()) { - if (a instanceof org.jrubyparser.ast.DAsgnNode) { - names.add(((org.jrubyparser.ast.DAsgnNode) a).getName()); - } else if (a instanceof org.jrubyparser.ast.MultipleAsgnNode) { - getNamesFromMultipleAssignment((org.jrubyparser.ast.MultipleAsgnNode) a, names); - } else if (a instanceof org.jrubyparser.ast.LocalAsgnNode) { - names.add(((org.jrubyparser.ast.LocalAsgnNode) a).getName()); - } else { - throw new RuntimeException(a.getClass().getName()); - } - } - } - - @Override - public Object visitSuperNode(org.jrubyparser.ast.SuperNode node) { - final SourceSection sourceSection = translate(node.getPosition()); - - final ArgumentsAndBlockTranslation argumentsAndBlock = translateArgumentsAndBlock(sourceSection, node.getIter(), node.getArgs(), null); - - final String name = environment.getMethodName(); - - return new GeneralSuperCallNode(context, sourceSection, name, argumentsAndBlock.getBlock(), argumentsAndBlock.getArguments(), argumentsAndBlock.isSplatted()); - } - - @Override - public Object visitZSuperNode(org.jrubyparser.ast.ZSuperNode node) { - final SourceSection sourceSection = translate(node.getPosition()); - - final ArgumentsAndBlockTranslation argumentsAndBlock = translateArgumentsAndBlock(sourceSection, node.getIter(), null, null); - - final String name = environment.getMethodName(); - - return new GeneralSuperCallNode(context, sourceSection, name, argumentsAndBlock.getBlock(), argumentsAndBlock.getArguments(), argumentsAndBlock.isSplatted()); - } - - @Override - protected FlipFlopStateNode createFlipFlopState(SourceSection sourceSection, int depth) { - if (isBlock) { - environment.setNeedsDeclarationFrame(); - return parent.createFlipFlopState(sourceSection, depth + 1); - } else { - return super.createFlipFlopState(sourceSection, depth); - } - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/ModuleTranslator.java --- a/graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/ModuleTranslator.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,134 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.parser; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.nodes.constants.*; -import com.oracle.truffle.ruby.nodes.control.*; -import com.oracle.truffle.ruby.nodes.literal.*; -import com.oracle.truffle.ruby.nodes.methods.*; -import com.oracle.truffle.ruby.nodes.objects.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.methods.*; - -/** - * Translates module and class nodes. - *

- * In Ruby, a module or class definition is somewhat like a method. It has a local scope and a value - * for self, which is the module or class object that is being defined. Therefore for a module or - * class definition we translate into a special method. We run that method with self set to be the - * newly allocated module or class. We then have to treat at least method and constant definitions - * differently. - */ -class ModuleTranslator extends Translator { - - public ModuleTranslator(RubyContext context, Translator parent, TranslatorEnvironment environment, Source source) { - super(context, parent, environment, source); - } - - public MethodDefinitionNode compileClassNode(org.jrubyparser.SourcePosition sourcePosition, String name, org.jrubyparser.ast.Node bodyNode) { - final SourceSection sourceSection = translate(sourcePosition); - - environment.addMethodDeclarationSlots(); - - final String methodName = "(" + name + "-def" + ")"; - environment.setMethodName(methodName); - - RubyNode body; - - if (bodyNode != null) { - body = (RubyNode) bodyNode.accept(this); - } else { - body = new NilNode(context, sourceSection); - } - - if (environment.getFlipFlopStates().size() > 0) { - body = new SequenceNode(context, sourceSection, initFlipFlopStates(sourceSection), body); - } - - body = new CatchReturnNode(context, sourceSection, body, environment.getReturnID()); - - final RubyRootNode pristineRootNode = new RubyRootNode(sourceSection, environment.getFrameDescriptor(), methodName, body); - - final CallTarget callTarget = Truffle.getRuntime().createCallTarget(NodeUtil.cloneNode(pristineRootNode)); - - return new MethodDefinitionNode(context, sourceSection, methodName, environment.getUniqueMethodIdentifier(), environment.getFrameDescriptor(), environment.needsDeclarationFrame(), - pristineRootNode, callTarget); - } - - @Override - public Object visitConstDeclNode(org.jrubyparser.ast.ConstDeclNode node) { - final SourceSection sourceSection = translate(node.getPosition()); - - final SelfNode selfNode = new SelfNode(context, sourceSection); - - return new WriteConstantNode(context, sourceSection, node.getName(), selfNode, (RubyNode) node.getValue().accept(this)); - } - - @Override - public Object visitConstNode(org.jrubyparser.ast.ConstNode node) { - final SourceSection sourceSection = translate(node.getPosition()); - - final SelfNode selfNode = new SelfNode(context, sourceSection); - - return new UninitializedReadConstantNode(context, sourceSection, node.getName(), selfNode); - } - - @Override - public Object visitDefnNode(org.jrubyparser.ast.DefnNode node) { - /* - * The top-level translator puts methods into Object. We put ours into the self, which is - * the class being defined. - */ - - final TranslatorEnvironment newEnvironment = new TranslatorEnvironment(context, environment, environment.getParser(), environment.getParser().allocateReturnID(), true, true, - new UniqueMethodIdentifier()); - final MethodTranslator methodCompiler = new MethodTranslator(context, this, newEnvironment, false, source); - final MethodDefinitionNode functionExprNode = methodCompiler.compileFunctionNode(translate(node.getPosition()), node.getName(), node.getArgs(), node.getBody()); - - final SourceSection sourceSection = translate(node.getPosition()); - return new AddMethodNode(context, sourceSection, new SelfNode(context, sourceSection), functionExprNode); - } - - @Override - public Object visitClassVarAsgnNode(org.jrubyparser.ast.ClassVarAsgnNode node) { - final SourceSection sourceSection = translate(node.getPosition()); - - final RubyNode receiver = new SelfNode(context, sourceSection); - - final RubyNode rhs = (RubyNode) node.getValue().accept(this); - - return new WriteClassVariableNode(context, sourceSection, node.getName(), receiver, rhs); - } - - @Override - public Object visitClassVarNode(org.jrubyparser.ast.ClassVarNode node) { - final SourceSection sourceSection = translate(node.getPosition()); - return new ReadClassVariableNode(context, sourceSection, node.getName(), new SelfNode(context, sourceSection)); - } - - @Override - public Object visitAliasNode(org.jrubyparser.ast.AliasNode node) { - final SourceSection sourceSection = translate(node.getPosition()); - - final org.jrubyparser.ast.LiteralNode oldName = (org.jrubyparser.ast.LiteralNode) node.getOldName(); - final org.jrubyparser.ast.LiteralNode newName = (org.jrubyparser.ast.LiteralNode) node.getNewName(); - - return new AliasNode(context, sourceSection, new SelfNode(context, sourceSection), newName.getName(), oldName.getName()); - } - - @Override - protected RubyNode getModuleToDefineModulesIn(SourceSection sourceSection) { - return new SelfNode(context, sourceSection); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/RubyFrameTypeConversion.java --- a/graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/RubyFrameTypeConversion.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.parser; - -import com.oracle.truffle.api.impl.*; -import com.oracle.truffle.ruby.runtime.*; - -public final class RubyFrameTypeConversion extends DefaultFrameTypeConversion { - - private static final RubyFrameTypeConversion INSTANCE = new RubyFrameTypeConversion(); - - private RubyFrameTypeConversion() { - } - - @Override - public Object getDefaultValue() { - return NilPlaceholder.INSTANCE; - } - - public static RubyFrameTypeConversion getInstance() { - return INSTANCE; - } -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/RubyNodeInstrumenter.java --- a/graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/RubyNodeInstrumenter.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.ruby.parser; - -import com.oracle.truffle.api.nodes.instrument.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.runtime.methods.*; - -public interface RubyNodeInstrumenter { - - /** - * Adds instrumentation support at a node that should be considered a member of - * {@link NodePhylum#STATEMENT}, possibly returning a new {@link InstrumentationProxyNode} that - * holds the original as its child. - */ - RubyNode instrumentAsStatement(RubyNode node); - - /** - * Adds instrumentation support at a node that should be considered a member of - * {@link NodePhylum#CALL}, possibly returning a new {@link InstrumentationProxyNode} that holds - * the original as its child. - */ - RubyNode instrumentAsCall(RubyNode node, String callName); - - /** - * Adds instrumentation support at a node that should be considered a member of - * {@link NodePhylum#ASSIGNMENT}, possibly returning a new {@link InstrumentationProxyNode} that - * holds the original as its child. - */ - RubyNode instrumentAsLocalAssignment(RubyNode node, UniqueMethodIdentifier methodIdentifier, String localName); - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/Translator.java --- a/graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/Translator.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2064 +0,0 @@ -/* - * Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.parser; - -import java.math.*; -import java.util.*; -import java.util.regex.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.impl.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.nodes.call.*; -import com.oracle.truffle.ruby.nodes.cast.*; -import com.oracle.truffle.ruby.nodes.constants.*; -import com.oracle.truffle.ruby.nodes.control.*; -import com.oracle.truffle.ruby.nodes.core.*; -import com.oracle.truffle.ruby.nodes.literal.*; -import com.oracle.truffle.ruby.nodes.literal.array.*; -import com.oracle.truffle.ruby.nodes.methods.*; -import com.oracle.truffle.ruby.nodes.methods.locals.*; -import com.oracle.truffle.ruby.nodes.objects.*; -import com.oracle.truffle.ruby.nodes.objects.instancevariables.*; -import com.oracle.truffle.ruby.nodes.yield.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.core.range.*; -import com.oracle.truffle.ruby.runtime.methods.*; - -/** - * A JRuby parser node visitor which translates JRuby AST nodes into our Ruby nodes, implementing a - * Ruby parser. Therefore there is some namespace contention here! We make all references to JRuby - * explicit. This is the only place though - it doesn't leak out elsewhere. - */ -public class Translator implements org.jrubyparser.NodeVisitor { - - protected final Translator parent; - - protected final RubyContext context; - protected final TranslatorEnvironment environment; - protected final Source source; - protected final RubyNodeInstrumenter instrumenter; - - private boolean translatingForStatement = false; - - private static final Map nodeDefinedNames = new HashMap<>(); - - static { - nodeDefinedNames.put(org.jrubyparser.ast.SelfNode.class, "self"); - nodeDefinedNames.put(org.jrubyparser.ast.NilNode.class, "nil"); - nodeDefinedNames.put(org.jrubyparser.ast.TrueNode.class, "true"); - nodeDefinedNames.put(org.jrubyparser.ast.FalseNode.class, "false"); - nodeDefinedNames.put(org.jrubyparser.ast.LocalAsgnNode.class, "assignment"); - nodeDefinedNames.put(org.jrubyparser.ast.DAsgnNode.class, "assignment"); - nodeDefinedNames.put(org.jrubyparser.ast.GlobalAsgnNode.class, "assignment"); - nodeDefinedNames.put(org.jrubyparser.ast.InstAsgnNode.class, "assignment"); - nodeDefinedNames.put(org.jrubyparser.ast.ClassVarAsgnNode.class, "assignment"); - nodeDefinedNames.put(org.jrubyparser.ast.OpAsgnAndNode.class, "assignment"); - nodeDefinedNames.put(org.jrubyparser.ast.OpAsgnOrNode.class, "assignment"); - nodeDefinedNames.put(org.jrubyparser.ast.OpAsgnNode.class, "assignment"); - nodeDefinedNames.put(org.jrubyparser.ast.OpElementAsgnNode.class, "assignment"); - nodeDefinedNames.put(org.jrubyparser.ast.MultipleAsgnNode.class, "assignment"); - nodeDefinedNames.put(org.jrubyparser.ast.GlobalVarNode.class, "global-variable"); - nodeDefinedNames.put(org.jrubyparser.ast.StrNode.class, "expression"); - nodeDefinedNames.put(org.jrubyparser.ast.DStrNode.class, "expression"); - nodeDefinedNames.put(org.jrubyparser.ast.FixnumNode.class, "expression"); - nodeDefinedNames.put(org.jrubyparser.ast.BignumNode.class, "expression"); - nodeDefinedNames.put(org.jrubyparser.ast.FloatNode.class, "expression"); - nodeDefinedNames.put(org.jrubyparser.ast.RegexpNode.class, "expression"); - nodeDefinedNames.put(org.jrubyparser.ast.DRegexpNode.class, "expression"); - nodeDefinedNames.put(org.jrubyparser.ast.ArrayNode.class, "expression"); - nodeDefinedNames.put(org.jrubyparser.ast.HashNode.class, "expression"); - nodeDefinedNames.put(org.jrubyparser.ast.SymbolNode.class, "expression"); - nodeDefinedNames.put(org.jrubyparser.ast.DotNode.class, "expression"); - nodeDefinedNames.put(org.jrubyparser.ast.NotNode.class, "expression"); - nodeDefinedNames.put(org.jrubyparser.ast.AndNode.class, "expression"); - nodeDefinedNames.put(org.jrubyparser.ast.OrNode.class, "expression"); - nodeDefinedNames.put(org.jrubyparser.ast.LocalVarNode.class, "local-variable"); - nodeDefinedNames.put(org.jrubyparser.ast.DVarNode.class, "local-variable"); - } - - /** - * Global variables which in common usage have frame local semantics. - */ - public static final Set FRAME_LOCAL_GLOBAL_VARIABLES = new HashSet<>(Arrays.asList("$_")); - - public Translator(RubyContext context, Translator parent, TranslatorEnvironment environment, Source source) { - this.context = context; - this.parent = parent; - this.environment = environment; - this.source = source; - this.instrumenter = environment.getNodeInstrumenter(); - } - - @Override - public Object visitAliasNode(org.jrubyparser.ast.AliasNode node) { - final SourceSection sourceSection = translate(node.getPosition()); - - final org.jrubyparser.ast.LiteralNode oldName = (org.jrubyparser.ast.LiteralNode) node.getOldName(); - final org.jrubyparser.ast.LiteralNode newName = (org.jrubyparser.ast.LiteralNode) node.getNewName(); - - final ClassNode classNode = new ClassNode(context, sourceSection, new SelfNode(context, sourceSection)); - - return new AliasNode(context, sourceSection, classNode, newName.getName(), oldName.getName()); - } - - @Override - public Object visitAndNode(org.jrubyparser.ast.AndNode node) { - final SourceSection sourceSection = translate(node.getPosition()); - - RubyNode x; - - if (node.getFirst() == null) { - x = new NilNode(context, sourceSection); - } else { - x = (RubyNode) node.getFirst().accept(this); - } - - RubyNode y; - - if (node.getSecond() == null) { - y = new NilNode(context, sourceSection); - } else { - y = (RubyNode) node.getSecond().accept(this); - } - - return AndNodeFactory.create(context, sourceSection, x, y); - } - - @Override - public Object visitArgsCatNode(org.jrubyparser.ast.ArgsCatNode node) { - final List nodes = new ArrayList<>(); - collectArgsCatNodes(nodes, node); - - final List translatedNodes = new ArrayList<>(); - - for (org.jrubyparser.ast.Node catNode : nodes) { - translatedNodes.add((RubyNode) catNode.accept(this)); - } - - return new ArrayConcatNode(context, translate(node.getPosition()), translatedNodes.toArray(new RubyNode[translatedNodes.size()])); - } - - // ArgsCatNodes can be nested - this collects them into a flat list of children - private void collectArgsCatNodes(List nodes, org.jrubyparser.ast.ArgsCatNode node) { - if (node.getFirst() instanceof org.jrubyparser.ast.ArgsCatNode) { - collectArgsCatNodes(nodes, (org.jrubyparser.ast.ArgsCatNode) node.getFirst()); - } else { - nodes.add(node.getFirst()); - } - - if (node.getSecond() instanceof org.jrubyparser.ast.ArgsCatNode) { - collectArgsCatNodes(nodes, (org.jrubyparser.ast.ArgsCatNode) node.getSecond()); - } else { - nodes.add(node.getSecond()); - } - } - - @Override - public Object visitArgsNode(org.jrubyparser.ast.ArgsNode node) { - return unimplemented(node); - } - - @Override - public Object visitArgsPushNode(org.jrubyparser.ast.ArgsPushNode node) { - return new ArrayPushNode(context, translate(node.getPosition()), (RubyNode) node.getFirstNode().accept(this), (RubyNode) node.getSecondNode().accept(this)); - } - - @Override - public Object visitArrayNode(org.jrubyparser.ast.ArrayNode node) { - final List values = node.childNodes(); - - final RubyNode[] translatedValues = new RubyNode[values.size()]; - - for (int n = 0; n < values.size(); n++) { - translatedValues[n] = (RubyNode) values.get(n).accept(this); - } - - return new UninitialisedArrayLiteralNode(context, translate(node.getPosition()), translatedValues); - } - - @Override - public Object visitAttrAssignNode(org.jrubyparser.ast.AttrAssignNode node) { - return visitAttrAssignNodeExtraArgument(node, null); - } - - /** - * See translateDummyAssignment to understand what this is for. - */ - public RubyNode visitAttrAssignNodeExtraArgument(org.jrubyparser.ast.AttrAssignNode node, RubyNode extraArgument) { - final org.jrubyparser.ast.CallNode callNode = new org.jrubyparser.ast.CallNode(node.getPosition(), node.getReceiver(), node.getName(), node.getArgs()); - return visitCallNodeExtraArgument(callNode, extraArgument); - } - - @Override - public Object visitBackRefNode(org.jrubyparser.ast.BackRefNode node) { - return unimplemented(node); - } - - @Override - public Object visitBeginNode(org.jrubyparser.ast.BeginNode node) { - return node.getBody().accept(this); - } - - @Override - public Object visitBignumNode(org.jrubyparser.ast.BignumNode node) { - return new BignumLiteralNode(context, translate(node.getPosition()), node.getValue()); - } - - @Override - public Object visitBlockArg18Node(org.jrubyparser.ast.BlockArg18Node node) { - return unimplemented(node); - } - - @Override - public Object visitBlockArgNode(org.jrubyparser.ast.BlockArgNode node) { - return unimplemented(node); - } - - @Override - public Object visitBlockNode(org.jrubyparser.ast.BlockNode node) { - final List children = node.childNodes(); - - final List translatedChildren = new ArrayList<>(); - - for (int n = 0; n < children.size(); n++) { - final RubyNode translatedChild = (RubyNode) children.get(n).accept(this); - - if (!(translatedChild instanceof DeadNode)) { - translatedChildren.add(translatedChild); - } - } - - if (translatedChildren.size() == 1) { - return translatedChildren.get(0); - } else { - return new SequenceNode(context, translate(node.getPosition()), translatedChildren.toArray(new RubyNode[translatedChildren.size()])); - } - } - - @Override - public Object visitBlockPassNode(org.jrubyparser.ast.BlockPassNode node) { - return unimplemented(node); - } - - @Override - public Object visitBreakNode(org.jrubyparser.ast.BreakNode node) { - final SourceSection sourceSection = translate(node.getPosition()); - - RubyNode resultNode; - - if (node.getValueNode() == null) { - resultNode = new NilNode(context, sourceSection); - } else { - resultNode = (RubyNode) node.getValueNode().accept(this); - } - - return new BreakNode(context, sourceSection, resultNode); - } - - @Override - public Object visitCallNode(org.jrubyparser.ast.CallNode node) { - return visitCallNodeExtraArgument(node, null); - } - - /** - * See translateDummyAssignment to understand what this is for. - */ - public RubyNode visitCallNodeExtraArgument(org.jrubyparser.ast.CallNode node, RubyNode extraArgument) { - final SourceSection sourceSection = translate(node.getPosition()); - - final RubyNode receiverTranslated = (RubyNode) node.getReceiver().accept(this); - - org.jrubyparser.ast.Node args = node.getArgs(); - org.jrubyparser.ast.Node block = node.getIter(); - - if (block == null && args instanceof org.jrubyparser.ast.IterNode) { - final org.jrubyparser.ast.Node temp = args; - args = block; - block = temp; - } - - final ArgumentsAndBlockTranslation argumentsAndBlock = translateArgumentsAndBlock(sourceSection, block, args, extraArgument); - - RubyNode translated = new CallNode(context, sourceSection, node.getName(), receiverTranslated, argumentsAndBlock.getBlock(), argumentsAndBlock.isSplatted(), argumentsAndBlock.getArguments()); - - return instrumenter.instrumentAsCall(translated, node.getName()); - } - - protected class ArgumentsAndBlockTranslation { - - private final RubyNode block; - private final RubyNode[] arguments; - private final boolean isSplatted; - - public ArgumentsAndBlockTranslation(RubyNode block, RubyNode[] arguments, boolean isSplatted) { - super(); - this.block = block; - this.arguments = arguments; - this.isSplatted = isSplatted; - } - - public RubyNode getBlock() { - return block; - } - - public RubyNode[] getArguments() { - return arguments; - } - - public boolean isSplatted() { - return isSplatted; - } - - } - - protected ArgumentsAndBlockTranslation translateArgumentsAndBlock(SourceSection sourceSection, org.jrubyparser.ast.Node iterNode, org.jrubyparser.ast.Node argsNode, RubyNode extraArgument) { - assert !(argsNode instanceof org.jrubyparser.ast.IterNode); - - final List arguments = new ArrayList<>(); - org.jrubyparser.ast.Node blockPassNode = null; - - boolean isSplatted = false; - - if (argsNode instanceof org.jrubyparser.ast.ListNode) { - arguments.addAll(((org.jrubyparser.ast.ListNode) argsNode).childNodes()); - } else if (argsNode instanceof org.jrubyparser.ast.BlockPassNode) { - final org.jrubyparser.ast.BlockPassNode blockPass = (org.jrubyparser.ast.BlockPassNode) argsNode; - - final org.jrubyparser.ast.Node blockPassArgs = blockPass.getArgs(); - - if (blockPassArgs instanceof org.jrubyparser.ast.ListNode) { - arguments.addAll(((org.jrubyparser.ast.ListNode) blockPassArgs).childNodes()); - } else if (blockPassArgs instanceof org.jrubyparser.ast.ArgsCatNode) { - arguments.add(blockPassArgs); - } else if (blockPassArgs != null) { - throw new UnsupportedOperationException("Don't know how to block pass " + blockPassArgs); - } - - blockPassNode = blockPass.getBody(); - } else if (argsNode instanceof org.jrubyparser.ast.SplatNode) { - isSplatted = true; - arguments.add(argsNode); - } else if (argsNode instanceof org.jrubyparser.ast.ArgsCatNode) { - isSplatted = true; - arguments.add(argsNode); - } else if (argsNode != null) { - isSplatted = true; - arguments.add(argsNode); - } - - RubyNode blockTranslated; - - if (blockPassNode != null && iterNode != null) { - throw new UnsupportedOperationException("Don't know how to pass both an block and a block-pass argument"); - } else if (iterNode != null) { - blockTranslated = (BlockDefinitionNode) iterNode.accept(this); - } else if (blockPassNode != null) { - blockTranslated = ProcCastNodeFactory.create(context, sourceSection, (RubyNode) blockPassNode.accept(this)); - } else { - blockTranslated = null; - } - - final List argumentsTranslated = new ArrayList<>(); - - for (org.jrubyparser.ast.Node argument : arguments) { - argumentsTranslated.add((RubyNode) argument.accept(this)); - } - - if (extraArgument != null) { - argumentsTranslated.add(extraArgument); - } - - final RubyNode[] argumentsTranslatedArray = argumentsTranslated.toArray(new RubyNode[argumentsTranslated.size()]); - - return new ArgumentsAndBlockTranslation(blockTranslated, argumentsTranslatedArray, isSplatted); - } - - @Override - public Object visitCaseNode(org.jrubyparser.ast.CaseNode node) { - final SourceSection sourceSection = translate(node.getPosition()); - - RubyNode elseNode; - - if (node.getElse() != null) { - elseNode = (RubyNode) node.getElse().accept(this); - } else { - elseNode = new NilNode(context, sourceSection); - } - - /* - * There are two sorts of case - one compares a list of expressions against a value, the - * other just checks a list of expressions for truth. - */ - - if (node.getCase() != null) { - // Evaluate the case expression and store it in a local - - final String tempName = environment.allocateLocalTemp(); - - final RubyNode readTemp = environment.findLocalVarNode(tempName, sourceSection); - - final RubyNode assignTemp = ((ReadNode) readTemp).makeWriteNode((RubyNode) node.getCase().accept(this)); - - /* - * Build an if expression from the whens and else. Work backwards because the first if - * contains all the others in its else clause. - */ - - for (int n = node.getCases().size() - 1; n >= 0; n--) { - final org.jrubyparser.ast.WhenNode when = (org.jrubyparser.ast.WhenNode) node.getCases().get(n); - - // Make a condition from the one or more expressions combined in an or expression - - final List expressions; - - if (when.getExpression() instanceof org.jrubyparser.ast.ListNode) { - expressions = ((org.jrubyparser.ast.ListNode) when.getExpression()).childNodes(); - } else { - expressions = Arrays.asList(when.getExpression()); - } - - final List comparisons = new ArrayList<>(); - - for (org.jrubyparser.ast.Node expressionNode : expressions) { - final RubyNode rubyExpression = (RubyNode) expressionNode.accept(this); - - final CallNode comparison = new CallNode(context, sourceSection, "===", rubyExpression, null, false, new RubyNode[]{environment.findLocalVarNode(tempName, sourceSection)}); - - comparisons.add(comparison); - } - - RubyNode conditionNode = comparisons.get(comparisons.size() - 1); - - // As with the if nodes, we work backwards to make it left associative - - for (int i = comparisons.size() - 2; i >= 0; i--) { - conditionNode = OrNodeFactory.create(context, sourceSection, comparisons.get(i), conditionNode); - } - - // Create the if node - - final BooleanCastNode conditionCastNode = BooleanCastNodeFactory.create(context, sourceSection, conditionNode); - - RubyNode thenNode; - - if (when.getBody() == null) { - thenNode = new NilNode(context, sourceSection); - } else { - thenNode = (RubyNode) when.getBody().accept(this); - } - - final IfNode ifNode = new IfNode(context, sourceSection, conditionCastNode, thenNode, elseNode); - - // This if becomes the else for the next if - - elseNode = ifNode; - } - - final RubyNode ifNode = elseNode; - - // A top-level block assigns the temp then runs the if - - return new SequenceNode(context, sourceSection, assignTemp, ifNode); - } else { - for (int n = node.getCases().size() - 1; n >= 0; n--) { - final org.jrubyparser.ast.WhenNode when = (org.jrubyparser.ast.WhenNode) node.getCases().get(n); - - // Make a condition from the one or more expressions combined in an or expression - - final List expressions; - - if (when.getExpression() instanceof org.jrubyparser.ast.ListNode) { - expressions = ((org.jrubyparser.ast.ListNode) when.getExpression()).childNodes(); - } else { - expressions = Arrays.asList(when.getExpression()); - } - - final List tests = new ArrayList<>(); - - for (org.jrubyparser.ast.Node expressionNode : expressions) { - final RubyNode rubyExpression = (RubyNode) expressionNode.accept(this); - tests.add(rubyExpression); - } - - RubyNode conditionNode = tests.get(tests.size() - 1); - - // As with the if nodes, we work backwards to make it left associative - - for (int i = tests.size() - 2; i >= 0; i--) { - conditionNode = OrNodeFactory.create(context, sourceSection, tests.get(i), conditionNode); - } - - // Create the if node - - final BooleanCastNode conditionCastNode = BooleanCastNodeFactory.create(context, sourceSection, conditionNode); - - final RubyNode thenNode = (RubyNode) when.getBody().accept(this); - - final IfNode ifNode = new IfNode(context, sourceSection, conditionCastNode, thenNode, elseNode); - - // This if becomes the else for the next if - - elseNode = ifNode; - } - - return elseNode; - } - } - - @Override - public Object visitClassNode(org.jrubyparser.ast.ClassNode node) { - final SourceSection sourceSection = translate(node.getPosition()); - - final String name = node.getCPath().getName(); - - final TranslatorEnvironment newEnvironment = new TranslatorEnvironment(context, environment, environment.getParser(), environment.getParser().allocateReturnID(), true, true, - new UniqueMethodIdentifier()); - final ModuleTranslator classTranslator = new ModuleTranslator(context, this, newEnvironment, source); - - final MethodDefinitionNode definitionMethod = classTranslator.compileClassNode(node.getPosition(), node.getCPath().getName(), node.getBody()); - - /* - * See my note in visitDefnNode about where the class gets defined - the same applies here. - */ - - RubyNode superClass; - - if (node.getSuper() != null) { - superClass = (RubyNode) node.getSuper().accept(this); - } else { - superClass = new ObjectLiteralNode(context, sourceSection, context.getCoreLibrary().getObjectClass()); - } - - final DefineOrGetClassNode defineOrGetClass = new DefineOrGetClassNode(context, sourceSection, name, getModuleToDefineModulesIn(sourceSection), superClass); - - return new OpenModuleNode(context, sourceSection, defineOrGetClass, definitionMethod); - } - - protected RubyNode getModuleToDefineModulesIn(SourceSection sourceSection) { - return new ClassNode(context, sourceSection, new SelfNode(context, sourceSection)); - } - - @Override - public Object visitClassVarAsgnNode(org.jrubyparser.ast.ClassVarAsgnNode node) { - final SourceSection sourceSection = translate(node.getPosition()); - - final RubyNode receiver = new ClassNode(context, sourceSection, new SelfNode(context, sourceSection)); - - final RubyNode rhs = (RubyNode) node.getValue().accept(this); - - return new WriteClassVariableNode(context, sourceSection, node.getName(), receiver, rhs); - } - - @Override - public Object visitClassVarDeclNode(org.jrubyparser.ast.ClassVarDeclNode node) { - return unimplemented(node); - } - - @Override - public Object visitClassVarNode(org.jrubyparser.ast.ClassVarNode node) { - final SourceSection sourceSection = translate(node.getPosition()); - return new ReadClassVariableNode(context, sourceSection, node.getName(), new SelfNode(context, sourceSection)); - } - - @Override - public Object visitColon2Node(org.jrubyparser.ast.Colon2Node node) { - final RubyNode lhs = (RubyNode) node.getLeftNode().accept(this); - - return new UninitializedReadConstantNode(context, translate(node.getPosition()), node.getName(), lhs); - } - - @Override - public Object visitColon3Node(org.jrubyparser.ast.Colon3Node node) { - // Colon3 means the root namespace, as in ::Foo - - final SourceSection sourceSection = translate(node.getPosition()); - - final ObjectLiteralNode root = new ObjectLiteralNode(context, sourceSection, context.getCoreLibrary().getMainObject()); - - return new UninitializedReadConstantNode(context, sourceSection, node.getName(), root); - } - - @Override - public Object visitConstDeclNode(org.jrubyparser.ast.ConstDeclNode node) { - final SourceSection sourceSection = translate(node.getPosition()); - - final ClassNode classNode = new ClassNode(context, sourceSection, new SelfNode(context, sourceSection)); - - return new WriteConstantNode(context, sourceSection, node.getName(), classNode, (RubyNode) node.getValue().accept(this)); - } - - @Override - public Object visitConstNode(org.jrubyparser.ast.ConstNode node) { - final SourceSection sourceSection = translate(node.getPosition()); - - return new UninitializedReadConstantNode(context, sourceSection, node.getName(), new SelfNode(context, sourceSection)); - } - - @Override - public Object visitDAsgnNode(org.jrubyparser.ast.DAsgnNode node) { - return new org.jrubyparser.ast.LocalAsgnNode(node.getPosition(), node.getName(), node.getDepth(), node.getValue()).accept(this); - } - - @Override - public Object visitDRegxNode(org.jrubyparser.ast.DRegexpNode node) { - SourceSection sourceSection = translate(node.getPosition()); - - final RubyNode stringNode = translateInterpolatedString(sourceSection, node.childNodes()); - - return StringToRegexpNodeFactory.create(context, sourceSection, stringNode); - } - - @Override - public Object visitDStrNode(org.jrubyparser.ast.DStrNode node) { - return translateInterpolatedString(translate(node.getPosition()), node.childNodes()); - } - - @Override - public Object visitDSymbolNode(org.jrubyparser.ast.DSymbolNode node) { - SourceSection sourceSection = translate(node.getPosition()); - - final RubyNode stringNode = translateInterpolatedString(sourceSection, node.childNodes()); - - return StringToSymbolNodeFactory.create(context, sourceSection, stringNode); - } - - private RubyNode translateInterpolatedString(SourceSection sourceSection, List childNodes) { - final List children = new ArrayList<>(); - - for (org.jrubyparser.ast.Node child : childNodes) { - children.add((RubyNode) child.accept(this)); - } - - return new InterpolatedStringNode(context, sourceSection, children.toArray(new RubyNode[children.size()])); - } - - @Override - public Object visitDVarNode(org.jrubyparser.ast.DVarNode node) { - RubyNode readNode = environment.findLocalVarNode(node.getName(), translate(node.getPosition())); - - if (readNode == null) { - context.implementationMessage("can't find variable %s at %s, using noop", node.getName(), node.getPosition()); - readNode = new NilNode(context, translate(node.getPosition())); - } - - return readNode; - } - - @Override - public Object visitDXStrNode(org.jrubyparser.ast.DXStrNode node) { - SourceSection sourceSection = translate(node.getPosition()); - - final RubyNode string = translateInterpolatedString(sourceSection, node.childNodes()); - - return new SystemNode(context, sourceSection, string); - } - - @Override - public Object visitDefinedNode(org.jrubyparser.ast.DefinedNode node) { - final SourceSection sourceSection = translate(node.getPosition()); - - org.jrubyparser.ast.Node expressionNode = node.getExpression(); - - while (expressionNode instanceof org.jrubyparser.ast.NewlineNode) { - expressionNode = ((org.jrubyparser.ast.NewlineNode) expressionNode).getNextNode(); - } - - final String name = nodeDefinedNames.get(expressionNode.getClass()); - - if (name != null) { - final StringLiteralNode literal = new StringLiteralNode(context, sourceSection, name); - return literal; - } - - return new DefinedNode(context, sourceSection, (RubyNode) node.getExpression().accept(this)); - } - - @Override - public Object visitDefnNode(org.jrubyparser.ast.DefnNode node) { - final SourceSection sourceSection = translate(node.getPosition()); - final ClassNode classNode = new ClassNode(context, sourceSection, new SelfNode(context, sourceSection)); - return translateMethodDefinition(sourceSection, classNode, node.getName(), node.getArgs(), node.getBody()); - } - - @Override - public Object visitDefsNode(org.jrubyparser.ast.DefsNode node) { - final SourceSection sourceSection = translate(node.getPosition()); - - final RubyNode objectNode = (RubyNode) node.getReceiver().accept(this); - - final SingletonClassNode singletonClassNode = new SingletonClassNode(context, sourceSection, objectNode); - - return translateMethodDefinition(sourceSection, singletonClassNode, node.getName(), node.getArgs(), node.getBody()); - } - - private RubyNode translateMethodDefinition(SourceSection sourceSection, RubyNode classNode, String methodName, org.jrubyparser.ast.ArgsNode argsNode, org.jrubyparser.ast.Node bodyNode) { - final TranslatorEnvironment newEnvironment = new TranslatorEnvironment(context, environment, environment.getParser(), environment.getParser().allocateReturnID(), true, true, - new UniqueMethodIdentifier()); - - // ownScopeForAssignments is the same for the defined method as the current one. - - final MethodTranslator methodCompiler = new MethodTranslator(context, this, newEnvironment, false, source); - - final MethodDefinitionNode functionExprNode = methodCompiler.compileFunctionNode(sourceSection, methodName, argsNode, bodyNode); - - /* - * In the top-level, methods are defined in the class of the main object. This is - * counter-intuitive - I would have expected them to be defined in the singleton class. - * Apparently this is a design decision to make top-level methods sort of global. - * - * http://stackoverflow.com/questions/1761148/where-are-methods-defined-at-the-ruby-top-level - */ - - return new AddMethodNode(context, sourceSection, classNode, functionExprNode); - } - - @Override - public Object visitDotNode(org.jrubyparser.ast.DotNode node) { - final RubyNode begin = (RubyNode) node.getBegin().accept(this); - final RubyNode end = (RubyNode) node.getEnd().accept(this); - SourceSection sourceSection = translate(node.getPosition()); - - if (begin instanceof FixnumLiteralNode && end instanceof FixnumLiteralNode) { - final int beginValue = ((FixnumLiteralNode) begin).getValue(); - final int endValue = ((FixnumLiteralNode) end).getValue(); - - return new ObjectLiteralNode(context, sourceSection, new FixnumRange(context.getCoreLibrary().getRangeClass(), beginValue, endValue, node.isExclusive())); - } - // See RangeNode for why there is a node specifically for creating this one type - return RangeLiteralNodeFactory.create(context, sourceSection, node.isExclusive(), begin, end); - } - - @Override - public Object visitEncodingNode(org.jrubyparser.ast.EncodingNode node) { - return unimplemented(node); - } - - @Override - public Object visitEnsureNode(org.jrubyparser.ast.EnsureNode node) { - final RubyNode tryPart = (RubyNode) node.getBody().accept(this); - final RubyNode ensurePart = (RubyNode) node.getEnsure().accept(this); - return new EnsureNode(context, translate(node.getPosition()), tryPart, ensurePart); - } - - @Override - public Object visitEvStrNode(org.jrubyparser.ast.EvStrNode node) { - return node.getBody().accept(this); - } - - @Override - public Object visitFCallNode(org.jrubyparser.ast.FCallNode node) { - final org.jrubyparser.ast.Node receiver = new org.jrubyparser.ast.SelfNode(node.getPosition()); - final org.jrubyparser.ast.Node callNode = new org.jrubyparser.ast.CallNode(node.getPosition(), receiver, node.getName(), node.getArgs(), node.getIter()); - - return callNode.accept(this); - } - - @Override - public Object visitFalseNode(org.jrubyparser.ast.FalseNode node) { - return new BooleanLiteralNode(context, translate(node.getPosition()), false); - } - - @Override - public Object visitFixnumNode(org.jrubyparser.ast.FixnumNode node) { - final long value = node.getValue(); - - if (value >= RubyFixnum.MIN_VALUE && value <= RubyFixnum.MAX_VALUE) { - return new FixnumLiteralNode(context, translate(node.getPosition()), (int) value); - } - return new BignumLiteralNode(context, translate(node.getPosition()), BigInteger.valueOf(value)); - } - - @Override - public Object visitFlipNode(org.jrubyparser.ast.FlipNode node) { - final SourceSection sourceSection = translate(node.getPosition()); - - final RubyNode begin = (RubyNode) node.getBegin().accept(this); - final RubyNode end = (RubyNode) node.getEnd().accept(this); - - final BooleanCastNode beginCast = BooleanCastNodeFactory.create(context, sourceSection, begin); - final BooleanCastNode endCast = BooleanCastNodeFactory.create(context, sourceSection, end); - final FlipFlopStateNode stateNode = createFlipFlopState(sourceSection, 0); - - return new FlipFlopNode(context, sourceSection, beginCast, endCast, stateNode, node.isExclusive()); - } - - protected FlipFlopStateNode createFlipFlopState(SourceSection sourceSection, int depth) { - final FrameSlot frameSlot = environment.declareVar(environment.allocateLocalTemp()); - environment.getFlipFlopStates().add(frameSlot); - - if (depth == 0) { - return new LocalFlipFlopStateNode(sourceSection, frameSlot); - } else { - return new LevelFlipFlopStateNode(sourceSection, depth, frameSlot); - } - } - - @Override - public Object visitFloatNode(org.jrubyparser.ast.FloatNode node) { - return new FloatLiteralNode(context, translate(node.getPosition()), node.getValue()); - } - - @Override - public Object visitForNode(org.jrubyparser.ast.ForNode node) { - /** - * A Ruby for-loop, such as: - * - *

-         * for x in y
-         *     z = x
-         *     puts z
-         * end
-         * 
- * - * naively desugars to: - * - *
-         * y.each do |x|
-         *     z = x
-         *     puts z
-         * end
-         * 
- * - * The main difference is that z is always going to be local to the scope outside the block, - * so it's a bit more like: - * - *
-         * z = nil unless z is already defined
-         * y.each do |x|
-         *    z = x
-         *    puts x
-         * end
-         * 
- * - * Which forces z to be defined in the correct scope. The parser already correctly calls z a - * local, but then that causes us a problem as if we're going to translate to a block we - * need a formal parameter - not a local variable. My solution to this is to add a - * temporary: - * - *
-         * z = nil unless z is already defined
-         * y.each do |temp|
-         *    x = temp
-         *    z = x
-         *    puts x
-         * end
-         * 
- * - * We also need that temp because the expression assigned in the for could be index - * assignment, multiple assignment, or whatever: - * - *
-         * for x[0] in y
-         *     z = x[0]
-         *     puts z
-         * end
-         * 
- * - * http://blog.grayproductions.net/articles/the_evils_of_the_for_loop - * http://stackoverflow.com/questions/3294509/for-vs-each-in-ruby - * - * The other complication is that normal locals should be defined in the enclosing scope, - * unlike a normal block. We do that by setting a flag on this translator object when we - * visit the new iter, translatingForStatement, which we recognise when visiting an iter - * node. - * - * Finally, note that JRuby's terminology is strange here. Normally 'iter' is a different - * term for a block. Here, JRuby calls the object being iterated over the 'iter'. - */ - - final String temp = environment.allocateLocalTemp(); - - final org.jrubyparser.ast.Node receiver = node.getIter(); - - /* - * The x in for x in ... is like the nodes in multiple assignment - it has a dummy RHS which - * we need to replace with our temp. Just like in multiple assignment this is really awkward - * with the JRuby AST. - */ - - final org.jrubyparser.ast.LocalVarNode readTemp = new org.jrubyparser.ast.LocalVarNode(node.getPosition(), 0, temp); - final org.jrubyparser.ast.Node forVar = node.getVar(); - final org.jrubyparser.ast.Node assignTemp = setRHS(forVar, readTemp); - - final org.jrubyparser.ast.BlockNode bodyWithTempAssign = new org.jrubyparser.ast.BlockNode(node.getPosition()); - bodyWithTempAssign.add(assignTemp); - bodyWithTempAssign.add(node.getBody()); - - final org.jrubyparser.ast.ArgumentNode blockVar = new org.jrubyparser.ast.ArgumentNode(node.getPosition(), temp); - final org.jrubyparser.ast.ListNode blockArgsPre = new org.jrubyparser.ast.ListNode(node.getPosition(), blockVar); - final org.jrubyparser.ast.ArgsNode blockArgs = new org.jrubyparser.ast.ArgsNode(node.getPosition(), blockArgsPre, null, null, null, null, null, null); - final org.jrubyparser.ast.IterNode block = new org.jrubyparser.ast.IterNode(node.getPosition(), blockArgs, node.getScope(), bodyWithTempAssign); - - final org.jrubyparser.ast.CallNode callNode = new org.jrubyparser.ast.CallNode(node.getPosition(), receiver, "each", null, block); - - translatingForStatement = true; - final RubyNode translated = (RubyNode) callNode.accept(this); - translatingForStatement = false; - - return translated; - } - - private static org.jrubyparser.ast.Node setRHS(org.jrubyparser.ast.Node node, org.jrubyparser.ast.Node rhs) { - if (node instanceof org.jrubyparser.ast.LocalAsgnNode) { - final org.jrubyparser.ast.LocalAsgnNode localAsgnNode = (org.jrubyparser.ast.LocalAsgnNode) node; - return new org.jrubyparser.ast.LocalAsgnNode(node.getPosition(), localAsgnNode.getName(), 0, rhs); - } else if (node instanceof org.jrubyparser.ast.DAsgnNode) { - final org.jrubyparser.ast.DAsgnNode dAsgnNode = (org.jrubyparser.ast.DAsgnNode) node; - return new org.jrubyparser.ast.DAsgnNode(node.getPosition(), dAsgnNode.getName(), 0, rhs); - } else if (node instanceof org.jrubyparser.ast.MultipleAsgnNode) { - final org.jrubyparser.ast.MultipleAsgnNode multAsgnNode = (org.jrubyparser.ast.MultipleAsgnNode) node; - return new org.jrubyparser.ast.MultipleAsgnNode(node.getPosition(), multAsgnNode.getPre(), multAsgnNode.getRest(), multAsgnNode.getPost()); - } else if (node instanceof org.jrubyparser.ast.InstAsgnNode) { - final org.jrubyparser.ast.InstAsgnNode instAsgnNode = (org.jrubyparser.ast.InstAsgnNode) node; - return new org.jrubyparser.ast.InstAsgnNode(node.getPosition(), instAsgnNode.getName(), rhs); - } else if (node instanceof org.jrubyparser.ast.ClassVarAsgnNode) { - final org.jrubyparser.ast.ClassVarAsgnNode instAsgnNode = (org.jrubyparser.ast.ClassVarAsgnNode) node; - return new org.jrubyparser.ast.ClassVarAsgnNode(node.getPosition(), instAsgnNode.getName(), rhs); - } else if (node instanceof org.jrubyparser.ast.ConstDeclNode) { - final org.jrubyparser.ast.ConstDeclNode constDeclNode = (org.jrubyparser.ast.ConstDeclNode) node; - return new org.jrubyparser.ast.ConstDeclNode(node.getPosition(), constDeclNode.getName(), (org.jrubyparser.ast.INameNode) constDeclNode.getConstNode(), rhs); - } else { - throw new UnsupportedOperationException("Don't know how to set the RHS of a " + node.getClass().getName()); - } - } - - @Override - public Object visitGlobalAsgnNode(org.jrubyparser.ast.GlobalAsgnNode node) { - final SourceSection sourceSection = translate(node.getPosition()); - - final String name = "$" + node.getName(); - final RubyNode rhs = (RubyNode) node.getValue().accept(this); - - if (FRAME_LOCAL_GLOBAL_VARIABLES.contains(name)) { - context.implementationMessage("Assigning to frame local global variables not implemented at %s", node.getPosition()); - - return rhs; - } else { - final ObjectLiteralNode globalVariablesObjectNode = new ObjectLiteralNode(context, sourceSection, context.getCoreLibrary().getGlobalVariablesObject()); - - return new UninitializedWriteInstanceVariableNode(context, sourceSection, name, globalVariablesObjectNode, rhs); - } - } - - @Override - public Object visitGlobalVarNode(org.jrubyparser.ast.GlobalVarNode node) { - final String name = "$" + node.getName(); - final SourceSection sourceSection = translate(node.getPosition()); - - if (FRAME_LOCAL_GLOBAL_VARIABLES.contains(name)) { - // Assignment is implicit for many of these, so we need to declare when we use - - environment.declareVar(name); - - final RubyNode readNode = environment.findLocalVarNode(name, sourceSection); - - return readNode; - } else { - final ObjectLiteralNode globalVariablesObjectNode = new ObjectLiteralNode(context, sourceSection, context.getCoreLibrary().getGlobalVariablesObject()); - - return new UninitializedReadInstanceVariableNode(context, sourceSection, name, globalVariablesObjectNode); - } - } - - @Override - public Object visitHashNode(org.jrubyparser.ast.HashNode node) { - final SourceSection sourceSection = translate(node.getPosition()); - - final List keys = new ArrayList<>(); - final List values = new ArrayList<>(); - - final org.jrubyparser.ast.ListNode entries = node.getListNode(); - - assert entries.size() % 2 == 0; - - for (int n = 0; n < entries.size(); n += 2) { - if (entries.get(n) == null) { - final NilNode nilNode = new NilNode(context, sourceSection); - keys.add(nilNode); - } else { - keys.add((RubyNode) entries.get(n).accept(this)); - } - - if (entries.get(n + 1) == null) { - final NilNode nilNode = new NilNode(context, sourceSection); - values.add(nilNode); - } else { - values.add((RubyNode) entries.get(n + 1).accept(this)); - } - } - - return new HashLiteralNode(translate(node.getPosition()), keys.toArray(new RubyNode[keys.size()]), values.toArray(new RubyNode[values.size()]), context); - } - - @Override - public Object visitIfNode(org.jrubyparser.ast.IfNode node) { - final SourceSection sourceSection = translate(node.getPosition()); - - org.jrubyparser.ast.Node thenBody = node.getThenBody(); - - if (thenBody == null) { - thenBody = new org.jrubyparser.ast.NilNode(node.getPosition()); - } - - org.jrubyparser.ast.Node elseBody = node.getElseBody(); - - if (elseBody == null) { - elseBody = new org.jrubyparser.ast.NilNode(node.getPosition()); - } - - RubyNode condition; - - if (node.getCondition() == null) { - condition = new NilNode(context, sourceSection); - } else { - condition = (RubyNode) node.getCondition().accept(this); - } - - final BooleanCastNode conditionCast = BooleanCastNodeFactory.create(context, sourceSection, condition); - - final RubyNode thenBodyTranslated = (RubyNode) thenBody.accept(this); - final RubyNode elseBodyTranslated = (RubyNode) elseBody.accept(this); - - return new IfNode(context, sourceSection, conditionCast, thenBodyTranslated, elseBodyTranslated); - } - - @Override - public Object visitInstAsgnNode(org.jrubyparser.ast.InstAsgnNode node) { - final SourceSection sourceSection = translate(node.getPosition()); - final String nameWithoutSigil = node.getName(); - - final RubyNode receiver = new SelfNode(context, sourceSection); - - RubyNode rhs; - - if (node.getValue() == null) { - rhs = new DeadNode(context, sourceSection); - } else { - rhs = (RubyNode) node.getValue().accept(this); - } - - return new UninitializedWriteInstanceVariableNode(context, sourceSection, nameWithoutSigil, receiver, rhs); - } - - @Override - public Object visitInstVarNode(org.jrubyparser.ast.InstVarNode node) { - final SourceSection sourceSection = translate(node.getPosition()); - final String nameWithoutSigil = node.getName(); - - final RubyNode receiver = new SelfNode(context, sourceSection); - - return new UninitializedReadInstanceVariableNode(context, sourceSection, nameWithoutSigil, receiver); - } - - @Override - public Object visitIterNode(org.jrubyparser.ast.IterNode node) { - /* - * In a block we do NOT allocate a new return ID - returns will return from the method, not - * the block (in the general case, see Proc and the difference between Proc and Lambda for - * specifics). - */ - - final boolean hasOwnScope = !translatingForStatement; - - // Unset this flag for any for any blocks within the for statement's body - - translatingForStatement = false; - - final TranslatorEnvironment newEnvironment = new TranslatorEnvironment(context, environment, environment.getParser(), environment.getReturnID(), hasOwnScope, false, - new UniqueMethodIdentifier()); - final MethodTranslator methodCompiler = new MethodTranslator(context, this, newEnvironment, true, source); - - org.jrubyparser.ast.ArgsNode argsNode; - - if (node.getVar() instanceof org.jrubyparser.ast.ArgsNode) { - argsNode = (org.jrubyparser.ast.ArgsNode) node.getVar(); - } else if (node.getVar() instanceof org.jrubyparser.ast.DAsgnNode) { - final org.jrubyparser.ast.ArgumentNode arg = new org.jrubyparser.ast.ArgumentNode(node.getPosition(), ((org.jrubyparser.ast.DAsgnNode) node.getVar()).getName()); - final org.jrubyparser.ast.ListNode preArgs = new org.jrubyparser.ast.ArrayNode(node.getPosition(), arg); - argsNode = new org.jrubyparser.ast.ArgsNode(node.getPosition(), preArgs, null, null, null, null, null, null); - } else if (node.getVar() == null) { - argsNode = null; - } else { - throw new UnsupportedOperationException(); - } - - return methodCompiler.compileFunctionNode(translate(node.getPosition()), "(block)", argsNode, node.getBody()); - } - - @Override - public Object visitLiteralNode(org.jrubyparser.ast.LiteralNode node) { - return unimplemented(node); - } - - @Override - public Object visitLocalAsgnNode(org.jrubyparser.ast.LocalAsgnNode node) { - final SourceSection sourceSection = translate(node.getPosition()); - - if (environment.getNeverAssignInParentScope()) { - environment.declareVar(node.getName()); - } - - RubyNode lhs = environment.findLocalVarNode(node.getName(), sourceSection); - - if (lhs == null) { - if (environment.hasOwnScopeForAssignments()) { - environment.declareVar(node.getName()); - } - - TranslatorEnvironment environmentToDeclareIn = environment; - - while (!environmentToDeclareIn.hasOwnScopeForAssignments()) { - environmentToDeclareIn = environmentToDeclareIn.getParent(); - } - - environmentToDeclareIn.declareVar(node.getName()); - lhs = environment.findLocalVarNode(node.getName(), sourceSection); - - if (lhs == null) { - throw new RuntimeException("shoudln't be here"); - } - } - - RubyNode rhs; - - if (node.getValue() == null) { - rhs = new DeadNode(context, sourceSection); - } else { - rhs = (RubyNode) node.getValue().accept(this); - } - - RubyNode translated = ((ReadNode) lhs).makeWriteNode(rhs); - - final UniqueMethodIdentifier methodIdentifier = environment.findMethodForLocalVar(node.getName()); - - return instrumenter.instrumentAsLocalAssignment(translated, methodIdentifier, node.getName()); - } - - @Override - public Object visitLocalVarNode(org.jrubyparser.ast.LocalVarNode node) { - final SourceSection sourceSection = translate(node.getPosition()); - - final String name = node.getName(); - - RubyNode readNode = environment.findLocalVarNode(name, sourceSection); - - if (readNode == null) { - context.implementationMessage("Local variable found by parser but not by translator - " + name + " at " + node.getPosition()); - readNode = environment.findLocalVarNode(environment.allocateLocalTemp(), sourceSection); - } - - return readNode; - } - - @Override - public Object visitMatch2Node(org.jrubyparser.ast.Match2Node node) { - final org.jrubyparser.ast.Node argsNode = buildArrayNode(node.getPosition(), node.getValue()); - final org.jrubyparser.ast.Node callNode = new org.jrubyparser.ast.CallNode(node.getPosition(), node.getReceiver(), "=~", argsNode, null); - return callNode.accept(this); - } - - @Override - public Object visitMatch3Node(org.jrubyparser.ast.Match3Node node) { - final org.jrubyparser.ast.Node argsNode = buildArrayNode(node.getPosition(), node.getValue()); - final org.jrubyparser.ast.Node callNode = new org.jrubyparser.ast.CallNode(node.getPosition(), node.getReceiver(), "=~", argsNode, null); - return callNode.accept(this); - } - - @Override - public Object visitMatchNode(org.jrubyparser.ast.MatchNode node) { - return unimplemented(node); - } - - @Override - public Object visitModuleNode(org.jrubyparser.ast.ModuleNode node) { - // See visitClassNode - - final SourceSection sourceSection = translate(node.getPosition()); - - final String name = node.getCPath().getName(); - - final TranslatorEnvironment newEnvironment = new TranslatorEnvironment(context, environment, environment.getParser(), environment.getParser().allocateReturnID(), true, true, - new UniqueMethodIdentifier()); - final ModuleTranslator classTranslator = new ModuleTranslator(context, this, newEnvironment, source); - - final MethodDefinitionNode definitionMethod = classTranslator.compileClassNode(node.getPosition(), node.getCPath().getName(), node.getBody()); - - final DefineOrGetModuleNode defineModuleNode = new DefineOrGetModuleNode(context, sourceSection, name, getModuleToDefineModulesIn(sourceSection)); - - return new OpenModuleNode(context, sourceSection, defineModuleNode, definitionMethod); - } - - @Override - public Object visitMultipleAsgnNode(org.jrubyparser.ast.MultipleAsgnNode node) { - final SourceSection sourceSection = translate(node.getPosition()); - - final org.jrubyparser.ast.ArrayNode preArray = (org.jrubyparser.ast.ArrayNode) node.getPre(); - final org.jrubyparser.ast.Node rhs = node.getValue(); - - RubyNode rhsTranslated; - - if (rhs == null) { - context.implementationMessage("warning: no RHS for multiple assignment - using noop"); - rhsTranslated = new NilNode(context, sourceSection); - } else { - rhsTranslated = (RubyNode) rhs.accept(this); - } - - /* - * One very common case is to do - * - * a, b = c, d - */ - - if (preArray != null && node.getPost() == null && node.getRest() == null && rhsTranslated instanceof UninitialisedArrayLiteralNode && - ((UninitialisedArrayLiteralNode) rhsTranslated).getValues().length == preArray.size()) { - /* - * We can deal with this common case be rewriting as - * - * temp1 = c; temp2 = d; a = temp1; b = temp2 - * - * We can't just do - * - * a = c; b = d - * - * As we don't know if d depends on the original value of a. - * - * We also need to return an array [c, d], but we make that result elidable so it isn't - * executed if it isn't actually demanded. - */ - - final RubyNode[] rhsValues = ((UninitialisedArrayLiteralNode) rhsTranslated).getValues(); - final int assignedValuesCount = preArray.size(); - - final RubyNode[] sequence = new RubyNode[assignedValuesCount * 2]; - - final RubyNode[] tempValues = new RubyNode[assignedValuesCount]; - - for (int n = 0; n < assignedValuesCount; n++) { - final String tempName = environment.allocateLocalTemp(); - final RubyNode readTemp = environment.findLocalVarNode(tempName, sourceSection); - final RubyNode assignTemp = ((ReadNode) readTemp).makeWriteNode(rhsValues[n]); - final RubyNode assignFinalValue = translateDummyAssignment(preArray.get(n), readTemp); - - sequence[n] = assignTemp; - sequence[assignedValuesCount + n] = assignFinalValue; - - tempValues[n] = readTemp; - } - - final RubyNode blockNode = new SequenceNode(context, sourceSection, sequence); - - final UninitialisedArrayLiteralNode arrayNode = new UninitialisedArrayLiteralNode(context, sourceSection, tempValues); - - final ElidableResultNode elidableResult = new ElidableResultNode(context, sourceSection, blockNode, arrayNode); - - return elidableResult; - } else if (preArray != null) { - /* - * The other simple case is - * - * a, b, c = x - * - * If x is an array, then it's - * - * a[0] = x[0] etc - * - * If x isn't an array then it's - * - * a, b, c = [x, nil, nil] - * - * Which I believe is the same effect as - * - * a, b, c, = *x - * - * So we insert the splat cast node, even though it isn't there. - */ - - /* - * Create a temp for the array. - */ - - final String tempName = environment.allocateLocalTemp(); - - /* - * Create a sequence of instructions, with the first being the literal array assigned to - * the temp. - */ - - final List sequence = new ArrayList<>(); - - final RubyNode splatCastNode = SplatCastNodeFactory.create(context, sourceSection, rhsTranslated); - - final RubyNode writeTemp = ((ReadNode) environment.findLocalVarNode(tempName, sourceSection)).makeWriteNode(splatCastNode); - - sequence.add(writeTemp); - - /* - * Then index the temp array for each assignment on the LHS. - */ - - for (int n = 0; n < preArray.size(); n++) { - final ArrayIndexNode assignedValue = ArrayIndexNodeFactory.create(context, sourceSection, n, environment.findLocalVarNode(tempName, sourceSection)); - - sequence.add(translateDummyAssignment(preArray.get(n), assignedValue)); - } - - if (node.getRest() != null) { - final ArrayRestNode assignedValue = new ArrayRestNode(context, sourceSection, preArray.size(), environment.findLocalVarNode(tempName, sourceSection)); - - sequence.add(translateDummyAssignment(node.getRest(), assignedValue)); - } - - return new SequenceNode(context, sourceSection, sequence.toArray(new RubyNode[sequence.size()])); - } else if (node.getPre() == null && node.getPost() == null && node.getRest() instanceof org.jrubyparser.ast.StarNode) { - return rhsTranslated; - } else if (node.getPre() == null && node.getPost() == null && node.getRest() != null && rhs != null && !(rhs instanceof org.jrubyparser.ast.ArrayNode)) { - /* - * *a = b - * - * >= 1.8, this seems to be the same as: - * - * a = *b - */ - - final RubyNode restTranslated = ((RubyNode) node.getRest().accept(this)).getNonProxyNode(); - - /* - * Sometimes rest is a corrupt write with no RHS, like in other multiple assignments, - * and sometimes it is already a read. - */ - - ReadNode restRead; - - if (restTranslated instanceof ReadNode) { - restRead = (ReadNode) restTranslated; - } else if (restTranslated instanceof WriteNode) { - restRead = (ReadNode) ((WriteNode) restTranslated).makeReadNode(); - } else { - throw new RuntimeException("Unknown form of multiple assignment " + node + " at " + node.getPosition()); - } - - final SplatCastNode rhsSplatCast = SplatCastNodeFactory.create(context, sourceSection, rhsTranslated); - - return restRead.makeWriteNode(rhsSplatCast); - } else if (node.getPre() == null && node.getPost() == null && node.getRest() != null && rhs != null && rhs instanceof org.jrubyparser.ast.ArrayNode) { - /* - * *a = [b, c] - * - * This seems to be the same as: - * - * a = [b, c] - */ - - final RubyNode restTranslated = ((RubyNode) node.getRest().accept(this)).getNonProxyNode(); - - /* - * Sometimes rest is a corrupt write with no RHS, like in other multiple assignments, - * and sometimes it is already a read. - */ - - ReadNode restRead; - - if (restTranslated instanceof ReadNode) { - restRead = (ReadNode) restTranslated; - } else if (restTranslated instanceof WriteNode) { - restRead = (ReadNode) ((WriteNode) restTranslated).makeReadNode(); - } else { - throw new RuntimeException("Unknown form of multiple assignment " + node + " at " + node.getPosition()); - } - - return restRead.makeWriteNode(rhsTranslated); - } else { - throw new RuntimeException("Unknown form of multiple assignment " + node + " at " + node.getPosition()); - } - } - - private RubyNode translateDummyAssignment(org.jrubyparser.ast.Node dummyAssignment, RubyNode rhs) { - final SourceSection sourceSection = translate(dummyAssignment.getPosition()); - - /* - * This is tricky. To represent the RHS of a multiple assignment they use corrupt assignment - * values, in some cases with no value to be assigned, and in other cases with a dummy - * value. We can't visit them normally, as they're corrupt. We can't just modify them to - * have our RHS, as that's a node in our AST, not theirs. We can't use a dummy value in - * their AST because I can't add new visitors to this interface. - */ - - RubyNode translated; - - if (dummyAssignment instanceof org.jrubyparser.ast.LocalAsgnNode) { - /* - * They have a dummy NilImplicitNode as the RHS. Translate, convert to read, convert to - * write which allows us to set the RHS. - */ - - final WriteNode dummyTranslated = (WriteNode) ((RubyNode) dummyAssignment.accept(this)).getNonProxyNode(); - translated = ((ReadNode) dummyTranslated.makeReadNode()).makeWriteNode(rhs); - } else if (dummyAssignment instanceof org.jrubyparser.ast.InstAsgnNode) { - /* - * Same as before, just a different type of assignment. - */ - - final WriteInstanceVariableNode dummyTranslated = (WriteInstanceVariableNode) dummyAssignment.accept(this); - translated = dummyTranslated.makeReadNode().makeWriteNode(rhs); - } else if (dummyAssignment instanceof org.jrubyparser.ast.AttrAssignNode) { - /* - * They've given us an AttrAssignNode with the final argument, the assigned value, - * missing. If we translate that we'll get foo.[]=(index), so missing the value. To - * solve we have a special version of the visitCallNode that allows us to pass another - * already translated argument, visitCallNodeExtraArgument. However, we initially have - * an AttrAssignNode, so we also need a special version of that. - */ - - final org.jrubyparser.ast.AttrAssignNode dummyAttrAssignment = (org.jrubyparser.ast.AttrAssignNode) dummyAssignment; - translated = visitAttrAssignNodeExtraArgument(dummyAttrAssignment, rhs); - } else if (dummyAssignment instanceof org.jrubyparser.ast.DAsgnNode) { - final RubyNode dummyTranslated = (RubyNode) dummyAssignment.accept(this); - - if (dummyTranslated.getNonProxyNode() instanceof WriteLevelVariableNode) { - translated = ((ReadNode) ((WriteLevelVariableNode) dummyTranslated.getNonProxyNode()).makeReadNode()).makeWriteNode(rhs); - } else { - translated = ((ReadNode) ((WriteLocalVariableNode) dummyTranslated.getNonProxyNode()).makeReadNode()).makeWriteNode(rhs); - } - } else { - translated = ((ReadNode) environment.findLocalVarNode(environment.allocateLocalTemp(), sourceSection)).makeWriteNode(rhs); - } - - return translated; - } - - @Override - public Object visitNewlineNode(org.jrubyparser.ast.NewlineNode node) { - RubyNode translated = (RubyNode) node.getNextNode().accept(this); - return instrumenter.instrumentAsStatement(translated); - } - - @Override - public Object visitNextNode(org.jrubyparser.ast.NextNode node) { - final SourceSection sourceSection = translate(node.getPosition()); - - RubyNode resultNode; - - if (node.getValueNode() == null) { - resultNode = new NilNode(context, sourceSection); - } else { - resultNode = (RubyNode) node.getValueNode().accept(this); - } - - return new NextNode(context, sourceSection, resultNode); - } - - @Override - public Object visitNilNode(org.jrubyparser.ast.NilNode node) { - return new NilNode(context, translate(node.getPosition())); - } - - @Override - public Object visitNotNode(org.jrubyparser.ast.NotNode node) { - final SourceSection sourceSection = translate(node.getPosition()); - - final BooleanCastNode booleanCastNode = BooleanCastNodeFactory.create(context, sourceSection, (RubyNode) node.getCondition().accept(this)); - - return new NotNode(context, sourceSection, booleanCastNode); - } - - @Override - public Object visitNthRefNode(org.jrubyparser.ast.NthRefNode node) { - final SourceSection sourceSection = translate(node.getPosition()); - - final String name = "$" + node.getMatchNumber(); - - RubyNode readLocal = environment.findLocalVarNode(name, sourceSection); - - if (readLocal == null) { - environment.declareVar(name); - readLocal = environment.findLocalVarNode(name, sourceSection); - } - - return readLocal; - } - - @Override - public Object visitOpAsgnAndNode(org.jrubyparser.ast.OpAsgnAndNode node) { - final org.jrubyparser.ast.Node lhs = node.getFirst(); - final org.jrubyparser.ast.Node rhs = node.getSecond(); - - return AndNodeFactory.create(context, translate(node.getPosition()), (RubyNode) lhs.accept(this), (RubyNode) rhs.accept(this)); - } - - @Override - public Object visitOpAsgnNode(org.jrubyparser.ast.OpAsgnNode node) { - /* - * We're going to de-sugar a.foo += c into a.foo = a.foo + c. Note that we can't evaluate a - * more than once, so we put it into a temporary, and we're doing something more like: - * - * temp = a; temp.foo = temp.foo + c - */ - - final String temp = environment.allocateLocalTemp(); - final org.jrubyparser.ast.Node writeReceiverToTemp = new org.jrubyparser.ast.LocalAsgnNode(node.getPosition(), temp, 0, node.getReceiver()); - final org.jrubyparser.ast.Node readReceiverFromTemp = new org.jrubyparser.ast.LocalVarNode(node.getPosition(), 0, temp); - - final org.jrubyparser.ast.Node readMethod = new org.jrubyparser.ast.CallNode(node.getPosition(), readReceiverFromTemp, node.getVariableName(), null); - final org.jrubyparser.ast.Node operation = new org.jrubyparser.ast.CallNode(node.getPosition(), readMethod, node.getOperatorName(), buildArrayNode(node.getPosition(), node.getValue())); - final org.jrubyparser.ast.Node writeMethod = new org.jrubyparser.ast.CallNode(node.getPosition(), readReceiverFromTemp, node.getVariableName() + "=", buildArrayNode(node.getPosition(), - operation)); - - final org.jrubyparser.ast.BlockNode block = new org.jrubyparser.ast.BlockNode(node.getPosition()); - block.add(writeReceiverToTemp); - block.add(writeMethod); - - return block.accept(this); - } - - @Override - public Object visitOpAsgnOrNode(org.jrubyparser.ast.OpAsgnOrNode node) { - /* - * De-sugar x ||= y into x || x = y. No repeated evaluations there so it's easy. It's also - * basically how jruby-parser represents it already. We'll do it directly, rather than via - * another JRuby AST node. - */ - - final org.jrubyparser.ast.Node lhs = node.getFirst(); - final org.jrubyparser.ast.Node rhs = node.getSecond(); - - return OrNodeFactory.create(context, translate(node.getPosition()), (RubyNode) lhs.accept(this), (RubyNode) rhs.accept(this)); - } - - @Override - public Object visitOpElementAsgnNode(org.jrubyparser.ast.OpElementAsgnNode node) { - /* - * We're going to de-sugar a[b] += c into a[b] = a[b] + c. See discussion in - * visitOpAsgnNode. - */ - - org.jrubyparser.ast.Node index; - - if (node.getArgs() == null) { - index = null; - } else { - index = node.getArgs().childNodes().get(0); - } - - final org.jrubyparser.ast.Node operand = node.getValue(); - - final String temp = environment.allocateLocalTemp(); - final org.jrubyparser.ast.Node writeArrayToTemp = new org.jrubyparser.ast.LocalAsgnNode(node.getPosition(), temp, 0, node.getReceiver()); - final org.jrubyparser.ast.Node readArrayFromTemp = new org.jrubyparser.ast.LocalVarNode(node.getPosition(), 0, temp); - - final org.jrubyparser.ast.Node arrayRead = new org.jrubyparser.ast.CallNode(node.getPosition(), readArrayFromTemp, "[]", buildArrayNode(node.getPosition(), index)); - - final String op = node.getOperatorName(); - - org.jrubyparser.ast.Node operation = null; - - if (op.equals("||")) { - operation = new org.jrubyparser.ast.OrNode(node.getPosition(), arrayRead, operand); - } else if (op.equals("&&")) { - operation = new org.jrubyparser.ast.AndNode(node.getPosition(), arrayRead, operand); - } else { - operation = new org.jrubyparser.ast.CallNode(node.getPosition(), arrayRead, node.getOperatorName(), buildArrayNode(node.getPosition(), operand)); - } - - final org.jrubyparser.ast.Node arrayWrite = new org.jrubyparser.ast.CallNode(node.getPosition(), readArrayFromTemp, "[]=", buildArrayNode(node.getPosition(), index, operation)); - - final org.jrubyparser.ast.BlockNode block = new org.jrubyparser.ast.BlockNode(node.getPosition()); - block.add(writeArrayToTemp); - block.add(arrayWrite); - - return block.accept(this); - } - - private static org.jrubyparser.ast.ArrayNode buildArrayNode(org.jrubyparser.SourcePosition sourcePosition, org.jrubyparser.ast.Node first, org.jrubyparser.ast.Node... rest) { - if (first == null) { - return new org.jrubyparser.ast.ArrayNode(sourcePosition); - } - - final org.jrubyparser.ast.ArrayNode array = new org.jrubyparser.ast.ArrayNode(sourcePosition, first); - - for (org.jrubyparser.ast.Node node : rest) { - array.add(node); - } - - return array; - } - - @Override - public Object visitOrNode(org.jrubyparser.ast.OrNode node) { - final SourceSection sourceSection = translate(node.getPosition()); - - RubyNode x; - - if (node.getFirst() == null) { - x = new NilNode(context, sourceSection); - } else { - x = (RubyNode) node.getFirst().accept(this); - } - - RubyNode y; - - if (node.getSecond() == null) { - y = new NilNode(context, sourceSection); - } else { - y = (RubyNode) node.getSecond().accept(this); - } - - return OrNodeFactory.create(context, sourceSection, x, y); - } - - @Override - public Object visitPostExeNode(org.jrubyparser.ast.PostExeNode node) { - return unimplemented(node); - } - - @Override - public Object visitPreExeNode(org.jrubyparser.ast.PreExeNode node) { - return unimplemented(node); - } - - @Override - public Object visitRedoNode(org.jrubyparser.ast.RedoNode node) { - return new RedoNode(context, translate(node.getPosition())); - } - - @Override - public Object visitRegexpNode(org.jrubyparser.ast.RegexpNode node) { - RubyRegexp regexp; - - try { - final String patternText = node.getValue(); - - int flags = Pattern.MULTILINE | Pattern.UNIX_LINES; - - final org.jrubyparser.RegexpOptions options = node.getOptions(); - - if (options.isIgnorecase()) { - flags |= Pattern.CASE_INSENSITIVE; - } - - if (options.isMultiline()) { - // TODO(cs): isn't this the default? - flags |= Pattern.MULTILINE; - } - - final Pattern pattern = Pattern.compile(patternText, flags); - - regexp = new RubyRegexp(context.getCoreLibrary().getRegexpClass(), pattern); - } catch (PatternSyntaxException e) { - context.implementationMessage("failed to parse Ruby regexp " + node.getValue() + " as Java regexp - replacing with ."); - regexp = new RubyRegexp(context.getCoreLibrary().getRegexpClass(), "."); - } - - final ObjectLiteralNode literalNode = new ObjectLiteralNode(context, translate(node.getPosition()), regexp); - return literalNode; - } - - @Override - public Object visitRescueBodyNode(org.jrubyparser.ast.RescueBodyNode node) { - return unimplemented(node); - } - - @Override - public Object visitRescueNode(org.jrubyparser.ast.RescueNode node) { - final SourceSection sourceSection = translate(node.getPosition()); - - RubyNode tryPart; - - if (node.getBody() != null) { - tryPart = (RubyNode) node.getBody().accept(this); - } else { - tryPart = new NilNode(context, sourceSection); - } - - final List rescueNodes = new ArrayList<>(); - - org.jrubyparser.ast.RescueBodyNode rescueBody = node.getRescue(); - - while (rescueBody != null) { - if (rescueBody.getExceptions() != null) { - if (rescueBody.getExceptions() instanceof org.jrubyparser.ast.ArrayNode) { - final List exceptionNodes = ((org.jrubyparser.ast.ArrayNode) rescueBody.getExceptions()).childNodes(); - - final RubyNode[] handlingClasses = new RubyNode[exceptionNodes.size()]; - - for (int n = 0; n < handlingClasses.length; n++) { - handlingClasses[n] = (RubyNode) exceptionNodes.get(n).accept(this); - } - - RubyNode translatedBody; - - if (rescueBody.getBody() == null) { - translatedBody = new NilNode(context, sourceSection); - } else { - translatedBody = (RubyNode) rescueBody.getBody().accept(this); - } - - final RescueClassesNode rescueNode = new RescueClassesNode(context, sourceSection, handlingClasses, translatedBody); - rescueNodes.add(rescueNode); - } else if (rescueBody.getExceptions() instanceof org.jrubyparser.ast.SplatNode) { - final org.jrubyparser.ast.SplatNode splat = (org.jrubyparser.ast.SplatNode) rescueBody.getExceptions(); - - RubyNode splatTranslated; - - if (splat.getValue() == null) { - splatTranslated = new NilNode(context, sourceSection); - } else { - splatTranslated = (RubyNode) splat.getValue().accept(this); - } - - RubyNode bodyTranslated; - - if (rescueBody.getBody() == null) { - bodyTranslated = new NilNode(context, sourceSection); - } else { - bodyTranslated = (RubyNode) rescueBody.getBody().accept(this); - } - - final RescueSplatNode rescueNode = new RescueSplatNode(context, sourceSection, splatTranslated, bodyTranslated); - rescueNodes.add(rescueNode); - } else { - unimplemented(node); - } - } else { - RubyNode bodyNode; - - if (rescueBody.getBody() == null) { - bodyNode = new NilNode(context, sourceSection); - } else { - bodyNode = (RubyNode) rescueBody.getBody().accept(this); - } - - final RescueAnyNode rescueNode = new RescueAnyNode(context, sourceSection, bodyNode); - rescueNodes.add(rescueNode); - } - - rescueBody = rescueBody.getOptRescue(); - } - - RubyNode elsePart; - - if (node.getElse() != null) { - elsePart = (RubyNode) node.getElse().accept(this); - } else { - elsePart = new NilNode(context, sourceSection); - } - - return new TryNode(context, sourceSection, tryPart, rescueNodes.toArray(new RescueNode[rescueNodes.size()]), elsePart); - } - - @Override - public Object visitRestArgNode(org.jrubyparser.ast.RestArgNode node) { - return unimplemented(node); - } - - @Override - public Object visitRetryNode(org.jrubyparser.ast.RetryNode node) { - return new RetryNode(context, translate(node.getPosition())); - } - - @Override - public Object visitReturnNode(org.jrubyparser.ast.ReturnNode node) { - final SourceSection sourceSection = translate(node.getPosition()); - - RubyNode translatedChild; - - if (node.getValue() == null) { - translatedChild = new NilNode(context, sourceSection); - } else { - translatedChild = (RubyNode) node.getValue().accept(this); - } - - return new ReturnNode(context, sourceSection, environment.getReturnID(), translatedChild); - } - - @Override - public Object visitRootNode(org.jrubyparser.ast.RootNode node) { - return unimplemented(node); - } - - @Override - public Object visitSClassNode(org.jrubyparser.ast.SClassNode node) { - final SourceSection sourceSection = translate(node.getPosition()); - - final TranslatorEnvironment newEnvironment = new TranslatorEnvironment(context, environment, environment.getParser(), environment.getParser().allocateReturnID(), true, true, - new UniqueMethodIdentifier()); - final ModuleTranslator classTranslator = new ModuleTranslator(context, this, newEnvironment, source); - - final MethodDefinitionNode definitionMethod = classTranslator.compileClassNode(node.getPosition(), "singleton", node.getBody()); - - final RubyNode receiverNode = (RubyNode) node.getReceiver().accept(this); - - final SingletonClassNode singletonClassNode = new SingletonClassNode(context, sourceSection, receiverNode); - - return new OpenModuleNode(context, sourceSection, singletonClassNode, definitionMethod); - } - - @Override - public Object visitSValueNode(org.jrubyparser.ast.SValueNode node) { - return node.getValue().accept(this); - } - - @Override - public Object visitSelfNode(org.jrubyparser.ast.SelfNode node) { - return new SelfNode(context, translate(node.getPosition())); - } - - @Override - public Object visitSplatNode(org.jrubyparser.ast.SplatNode node) { - final SourceSection sourceSection = translate(node.getPosition()); - - RubyNode value; - - if (node.getValue() == null) { - value = new NilNode(context, sourceSection); - } else { - value = (RubyNode) node.getValue().accept(this); - } - - return SplatCastNodeFactory.create(context, sourceSection, value); - } - - @Override - public Object visitStrNode(org.jrubyparser.ast.StrNode node) { - return new StringLiteralNode(context, translate(node.getPosition()), node.getValue()); - } - - @Override - public Object visitSuperNode(org.jrubyparser.ast.SuperNode node) { - return unimplemented(node); - } - - @Override - public Object visitSymbolNode(org.jrubyparser.ast.SymbolNode node) { - return new ObjectLiteralNode(context, translate(node.getPosition()), new RubySymbol(context.getCoreLibrary().getSymbolClass(), node.getName())); - } - - @Override - public Object visitToAryNode(org.jrubyparser.ast.ToAryNode node) { - return unimplemented(node); - } - - @Override - public Object visitTrueNode(org.jrubyparser.ast.TrueNode node) { - return new BooleanLiteralNode(context, translate(node.getPosition()), true); - } - - @Override - public Object visitUndefNode(org.jrubyparser.ast.UndefNode node) { - return unimplemented(node); - } - - @Override - public Object visitUntilNode(org.jrubyparser.ast.UntilNode node) { - final SourceSection sourceSection = translate(node.getPosition()); - - RubyNode condition; - - if (node.getCondition() == null) { - condition = new NilNode(context, sourceSection); - } else { - condition = (RubyNode) node.getCondition().accept(this); - } - - final BooleanCastNode conditionCast = BooleanCastNodeFactory.create(context, sourceSection, condition); - final NotNode conditionCastNot = new NotNode(context, sourceSection, conditionCast); - final BooleanCastNode conditionCastNotCast = BooleanCastNodeFactory.create(context, sourceSection, conditionCastNot); - - final RubyNode body = (RubyNode) node.getBody().accept(this); - - return new WhileNode(context, sourceSection, conditionCastNotCast, body); - } - - @Override - public Object visitVAliasNode(org.jrubyparser.ast.VAliasNode node) { - return unimplemented(node); - } - - @Override - public Object visitVCallNode(org.jrubyparser.ast.VCallNode node) { - final org.jrubyparser.ast.Node receiver = new org.jrubyparser.ast.SelfNode(node.getPosition()); - final org.jrubyparser.ast.Node args = null; - final org.jrubyparser.ast.Node callNode = new org.jrubyparser.ast.CallNode(node.getPosition(), receiver, node.getName(), args); - - return callNode.accept(this); - } - - @Override - public Object visitWhenNode(org.jrubyparser.ast.WhenNode node) { - return unimplemented(node); - } - - @Override - public Object visitWhileNode(org.jrubyparser.ast.WhileNode node) { - final SourceSection sourceSection = translate(node.getPosition()); - - RubyNode condition; - - if (node.getCondition() == null) { - condition = new NilNode(context, sourceSection); - } else { - condition = (RubyNode) node.getCondition().accept(this); - } - - final BooleanCastNode conditionCast = BooleanCastNodeFactory.create(context, sourceSection, condition); - - final RubyNode body = (RubyNode) node.getBody().accept(this); - - return new WhileNode(context, sourceSection, conditionCast, body); - } - - @Override - public Object visitXStrNode(org.jrubyparser.ast.XStrNode node) { - SourceSection sourceSection = translate(node.getPosition()); - - final StringLiteralNode literal = new StringLiteralNode(context, sourceSection, node.getValue()); - - return new SystemNode(context, sourceSection, literal); - } - - @Override - public Object visitYieldNode(org.jrubyparser.ast.YieldNode node) { - final List arguments = new ArrayList<>(); - - final org.jrubyparser.ast.Node argsNode = node.getArgs(); - - if (argsNode != null) { - if (argsNode instanceof org.jrubyparser.ast.ListNode) { - arguments.addAll(((org.jrubyparser.ast.ListNode) node.getArgs()).childNodes()); - } else { - arguments.add(node.getArgs()); - } - } - - final List argumentsTranslated = new ArrayList<>(); - - for (org.jrubyparser.ast.Node argument : arguments) { - argumentsTranslated.add((RubyNode) argument.accept(this)); - } - - final RubyNode[] argumentsTranslatedArray = argumentsTranslated.toArray(new RubyNode[argumentsTranslated.size()]); - - return new YieldNode(context, translate(node.getPosition()), argumentsTranslatedArray); - } - - @Override - public Object visitZArrayNode(org.jrubyparser.ast.ZArrayNode node) { - final RubyNode[] values = new RubyNode[0]; - - return new UninitialisedArrayLiteralNode(context, translate(node.getPosition()), values); - } - - @Override - public Object visitZSuperNode(org.jrubyparser.ast.ZSuperNode node) { - return unimplemented(node); - } - - public Object visitArgumentNode(org.jrubyparser.ast.ArgumentNode node) { - return unimplemented(node); - } - - public Object visitCommentNode(org.jrubyparser.ast.CommentNode node) { - return unimplemented(node); - } - - public Object visitKeywordArgNode(org.jrubyparser.ast.KeywordArgNode node) { - return unimplemented(node); - } - - public Object visitKeywordRestArgNode(org.jrubyparser.ast.KeywordRestArgNode node) { - return unimplemented(node); - } - - public Object visitListNode(org.jrubyparser.ast.ListNode node) { - return unimplemented(node); - } - - public Object visitMethodNameNode(org.jrubyparser.ast.MethodNameNode node) { - return unimplemented(node); - } - - public Object visitOptArgNode(org.jrubyparser.ast.OptArgNode node) { - return unimplemented(node); - } - - public Object visitSyntaxNode(org.jrubyparser.ast.SyntaxNode node) { - return unimplemented(node); - } - - public Object visitImplicitNilNode(org.jrubyparser.ast.ImplicitNilNode node) { - return new NilNode(context, translate(node.getPosition())); - } - - public Object visitLambdaNode(org.jrubyparser.ast.LambdaNode node) { - // TODO(cs): code copied and modified from visitIterNode - extract common - - final TranslatorEnvironment newEnvironment = new TranslatorEnvironment(context, environment, environment.getParser(), environment.getReturnID(), false, false, new UniqueMethodIdentifier()); - final MethodTranslator methodCompiler = new MethodTranslator(context, this, newEnvironment, false, source); - - org.jrubyparser.ast.ArgsNode argsNode; - - if (node.getVar() instanceof org.jrubyparser.ast.ArgsNode) { - argsNode = (org.jrubyparser.ast.ArgsNode) node.getVar(); - } else if (node.getVar() instanceof org.jrubyparser.ast.DAsgnNode) { - final org.jrubyparser.ast.ArgumentNode arg = new org.jrubyparser.ast.ArgumentNode(node.getPosition(), ((org.jrubyparser.ast.DAsgnNode) node.getVar()).getName()); - final org.jrubyparser.ast.ListNode preArgs = new org.jrubyparser.ast.ArrayNode(node.getPosition(), arg); - argsNode = new org.jrubyparser.ast.ArgsNode(node.getPosition(), preArgs, null, null, null, null, null, null); - } else if (node.getVar() == null) { - argsNode = null; - } else { - throw new UnsupportedOperationException(); - } - - final MethodDefinitionNode definitionNode = methodCompiler.compileFunctionNode(translate(node.getPosition()), "(lambda)", argsNode, node.getBody()); - - return new LambdaNode(context, translate(node.getPosition()), definitionNode); - } - - public Object visitUnaryCallNode(org.jrubyparser.ast.UnaryCallNode node) { - final org.jrubyparser.ast.Node callNode = new org.jrubyparser.ast.CallNode(node.getPosition(), node.getReceiver(), node.getName(), null, null); - return callNode.accept(this); - } - - protected Object unimplemented(org.jrubyparser.ast.Node node) { - context.implementationMessage("warning: %s at %s does nothing", node, node.getPosition()); - return new NilNode(context, translate(node.getPosition())); - } - - protected SourceSection translate(final org.jrubyparser.SourcePosition sourcePosition) { - try { - // TODO(cs): get an identifier - final String identifier = "(identifier)"; - - // TODO(cs): work out the start column - final int startColumn = -1; - - final int charLength = sourcePosition.getEndOffset() - sourcePosition.getStartOffset(); - - return new DefaultSourceSection(source, identifier, sourcePosition.getStartLine() + 1, startColumn, sourcePosition.getStartOffset(), charLength); - } catch (UnsupportedOperationException e) { - // In some circumstances JRuby can't tell you what the position is - return translate(new org.jrubyparser.SourcePosition("(unknown)", 0, 0)); - } - } - - protected SequenceNode initFlipFlopStates(SourceSection sourceSection) { - final RubyNode[] initNodes = new RubyNode[environment.getFlipFlopStates().size()]; - - for (int n = 0; n < initNodes.length; n++) { - initNodes[n] = new InitFlipFlopSlotNode(context, sourceSection, environment.getFlipFlopStates().get(n)); - } - - return new SequenceNode(context, sourceSection, initNodes); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/TranslatorEnvironment.java --- a/graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/TranslatorEnvironment.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,231 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.parser; - -import java.util.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.ruby.nodes.*; -import com.oracle.truffle.ruby.nodes.methods.locals.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.methods.*; - -public class TranslatorEnvironment { - - private final RubyContext context; - - private final FrameDescriptor frameDescriptor; - - private final List preParameters = new ArrayList<>(); - - private final List optionalParameters = new ArrayList<>(); - private final Map optionalParametersDefaultValues = new HashMap<>(); - - private final List postParameters = new ArrayList<>(); - - private final List flipFlopStates = new ArrayList<>(); - - private FrameSlot restParameter = null; - - private FrameSlot blockParameter = null; - - private JRubyParser parser; - private final long returnID; - - private final boolean ownScopeForAssignments; - private final boolean neverAssignInParentScope; - - protected final TranslatorEnvironment parent; - private String methodName = ""; - private boolean needsDeclarationFrame = false; - private UniqueMethodIdentifier methodIdentifier; - - private int tempIndex; - - public TranslatorEnvironment(RubyContext context, TranslatorEnvironment parent, FrameDescriptor frameDescriptor, JRubyParser parser, long returnID, boolean ownScopeForAssignments, - boolean neverAssignInParentScope, UniqueMethodIdentifier methodIdentifier) { - this.context = context; - this.parent = parent; - this.frameDescriptor = frameDescriptor; - this.parser = parser; - this.returnID = returnID; - this.ownScopeForAssignments = ownScopeForAssignments; - this.neverAssignInParentScope = neverAssignInParentScope; - this.methodIdentifier = methodIdentifier; - } - - public TranslatorEnvironment(RubyContext context, TranslatorEnvironment parent, JRubyParser parser, long returnID, boolean ownScopeForAssignments, boolean neverAssignInParentScope, - UniqueMethodIdentifier methodIdentifier) { - this(context, parent, new FrameDescriptor(RubyFrameTypeConversion.getInstance()), parser, returnID, ownScopeForAssignments, neverAssignInParentScope, methodIdentifier); - } - - public int getLocalVarCount() { - return getFrameDescriptor().getSize(); - } - - public TranslatorEnvironment getParent() { - return parent; - } - - public List getPreParameters() { - return preParameters; - } - - public List getOptionalParameters() { - return optionalParameters; - } - - public Map getOptionalParametersDefaultValues() { - return optionalParametersDefaultValues; - } - - public List getPostParameters() { - return postParameters; - } - - public TranslatorEnvironment getParent(int level) { - assert level >= 0; - if (level == 0) { - return this; - } else { - return parent.getParent(level - 1); - } - } - - public FrameSlot declareVar(String name) { - return getFrameDescriptor().findOrAddFrameSlot(name); - } - - public UniqueMethodIdentifier findMethodForLocalVar(String name) { - TranslatorEnvironment current = this; - do { - FrameSlot slot = current.getFrameDescriptor().findFrameSlot(name); - if (slot != null) { - return current.methodIdentifier; - } - - current = current.parent; - } while (current != null); - - return null; - } - - public RubyNode findLocalVarNode(String name, SourceSection sourceSection) { - TranslatorEnvironment current = this; - int level = -1; - try { - do { - level++; - FrameSlot slot = current.getFrameDescriptor().findFrameSlot(name); - if (slot != null) { - if (level == 0) { - return ReadLocalVariableNodeFactory.create(context, sourceSection, slot); - } else { - return ReadLevelVariableNodeFactory.create(context, sourceSection, slot, level); - } - } - - current = current.parent; - } while (current != null); - } finally { - if (current != null) { - current = this; - while (level-- > 0) { - current.needsDeclarationFrame = true; - current = current.parent; - } - } - } - - return null; - } - - public void setRestParameter(FrameSlot restParameter) { - this.restParameter = restParameter; - } - - public FrameSlot getRestParameter() { - return restParameter; - } - - public void setBlockParameter(FrameSlot blockParameter) { - this.blockParameter = blockParameter; - } - - public FrameSlot getBlockParameter() { - return blockParameter; - } - - public void declareFunction(String name) { - declareVar(name); - } - - public String getMethodName() { - return methodName; - } - - public void setMethodName(String methodName) { - this.methodName = methodName; - } - - public void setNeedsDeclarationFrame() { - needsDeclarationFrame = true; - } - - public boolean needsDeclarationFrame() { - return needsDeclarationFrame; - } - - public FrameDescriptor getFrameDescriptor() { - return frameDescriptor; - } - - public String allocateLocalTemp() { - final String name = "rubytruffle_temp" + tempIndex; - tempIndex++; - declareVar(name); - return name; - } - - public long getReturnID() { - return returnID; - } - - public JRubyParser getParser() { - return parser; - } - - public boolean hasOwnScopeForAssignments() { - return ownScopeForAssignments; - } - - public boolean getNeverAssignInParentScope() { - return neverAssignInParentScope; - } - - public void addMethodDeclarationSlots() { - frameDescriptor.addFrameSlot(RubyModule.VISIBILITY_FRAME_SLOT_ID); - frameDescriptor.addFrameSlot(RubyModule.MODULE_FUNCTION_FLAG_FRAME_SLOT_ID); - } - - public UniqueMethodIdentifier getUniqueMethodIdentifier() { - return methodIdentifier; - } - - public List getFlipFlopStates() { - return flipFlopStates; - } - - public RubyNodeInstrumenter getNodeInstrumenter() { - return parser.getNodeInstrumenter(); - } -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/.checkstyle_checks.xml --- a/graal/com.oracle.truffle.ruby.runtime/.checkstyle_checks.xml Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,206 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/InputReader.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/InputReader.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime; - -import java.io.*; - -/** - * Interface allowing Ruby {@code Kernel#gets} to be configured to use the standard Java readLine, - * some library like JLine, or to be mocked for testing. - */ -public interface InputReader { - - /** - * Show a prompt and read one line of input. - */ - String readLine(String prompt) throws IOException; - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/NilPlaceholder.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/NilPlaceholder.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime; - -/** - * Represents the Ruby {@code Nil} object, but without being a full Ruby object. This allows us to - * have a simple values that is {@code nil}, but more readily available than the particular instance - * for a context. - */ -public final class NilPlaceholder { - - public static final NilPlaceholder INSTANCE = new NilPlaceholder(); - - private NilPlaceholder() { - } - - @Override - public String toString() { - return ""; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/RubyArguments.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/RubyArguments.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.runtime.core.*; - -/** - * Arguments and other context passed to a Ruby method. Includes the central Ruby context object, - * optionally the scope at the point of declaration (forming a closure), the value of self, a passed - * block, and the formal arguments. - */ -public final class RubyArguments extends Arguments { - - private final MaterializedFrame declarationFrame; - private final Object self; - private final RubyProc block; - private final Object[] arguments; - - public RubyArguments(MaterializedFrame declarationFrame, Object self, RubyProc block, Object... arguments) { - assert self != null; - assert arguments != null; - - this.declarationFrame = declarationFrame; - this.self = self; - this.block = block; - this.arguments = arguments; - } - - public MaterializedFrame getDeclarationFrame() { - return declarationFrame; - } - - /** - * Get the declaration frame a certain number of levels up from the current frame, where the - * current frame is 0. - */ - public static MaterializedFrame getDeclarationFrame(VirtualFrame frame, int level) { - assert level > 0; - - MaterializedFrame parentFrame = frame.getArguments(RubyArguments.class).getDeclarationFrame(); - return getDeclarationFrame(parentFrame, level - 1); - } - - /** - * Get the declaration frame a certain number of levels up from the current frame, where the - * current frame is 0. - */ - @ExplodeLoop - private static MaterializedFrame getDeclarationFrame(MaterializedFrame frame, int level) { - assert frame != null; - assert level >= 0; - - MaterializedFrame parentFrame = frame; - - for (int n = 0; n < level; n++) { - parentFrame = parentFrame.getArguments(RubyArguments.class).getDeclarationFrame(); - } - - return parentFrame; - } - - public Object getSelf() { - return self; - } - - public RubyProc getBlock() { - return block; - } - - public Object[] getArguments() { - return arguments; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/RubyContext.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/RubyContext.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,310 +0,0 @@ -/* - * Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime; - -import java.math.*; -import java.util.concurrent.atomic.*; - -import jnr.posix.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.impl.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.ruby.runtime.configuration.*; -import com.oracle.truffle.ruby.runtime.control.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.debug.*; -import com.oracle.truffle.ruby.runtime.methods.*; -import com.oracle.truffle.ruby.runtime.objects.*; -import com.oracle.truffle.ruby.runtime.subsystems.*; - -/** - * The global state of a running Ruby system. - */ -public class RubyContext implements ExecutionContext { - - private final Configuration configuration; - private final RubyParser parser; - private final CoreLibrary coreLibrary; - private final FeatureManager featureManager; - private final ObjectSpaceManager objectSpaceManager; - private final TraceManager traceManager; - private final ThreadManager threadManager; - private final FiberManager fiberManager; - private final AtExitManager atExitManager; - private final DebugManager debugManager; - private final RubyDebugManager rubyDebugManager; - private final SourceManager sourceManager; - private final ASTPrinter astPrinter; - - private AtomicLong nextObjectID = new AtomicLong(0); - - private String currentDirectory = System.getProperty("user.dir"); - - private POSIX posix = POSIXFactory.getPOSIX(); - - public RubyContext(RubyParser parser) { - this(new Configuration(new ConfigurationBuilder()), parser, null); - } - - public RubyContext(Configuration configuration, RubyParser parser) { - this(configuration, parser, null); - } - - public RubyContext(Configuration configuration, RubyParser parser, ASTPrinter astPrinter) { - assert configuration != null; - - this.configuration = configuration; - this.parser = parser; - this.astPrinter = astPrinter; - - objectSpaceManager = new ObjectSpaceManager(this); - traceManager = new TraceManager(this); - - // See note in CoreLibrary#initialize to see why we need to break this into two statements - coreLibrary = new CoreLibrary(this); - coreLibrary.initialize(); - - featureManager = new FeatureManager(this); - atExitManager = new AtExitManager(); - sourceManager = new SourceManager(); - - debugManager = new DefaultDebugManager(this); - rubyDebugManager = new RubyDebugManager(); - - // Must initialize threads before fibers - - threadManager = new ThreadManager(this); - fiberManager = new FiberManager(this); - } - - public final String getLanguageShortName() { - return "Ruby " + CoreLibrary.RUBY_VERSION; - } - - public DebugManager getDebugManager() { - return debugManager; - } - - public ASTPrinter getASTPrinter() { - return astPrinter; - } - - public void implementationMessage(String format, Object... arguments) { - System.err.println("rubytruffle: " + String.format(format, arguments)); - } - - public void load(Source source) { - execute(this, source, RubyParser.ParserContext.TOP_LEVEL, coreLibrary.getMainObject(), null); - } - - public void loadFile(String fileName) { - final Source source = sourceManager.get(fileName); - final String code = source.getCode(); - if (code == null) { - throw new RuntimeException("Can't read file " + fileName); - } - execute(this, source, RubyParser.ParserContext.TOP_LEVEL, coreLibrary.getMainObject(), null); - } - - /** - * Receives runtime notification that execution has halted. - */ - public void haltedAt(Node node, MaterializedFrame frame) { - runShell(node, frame); - } - - public Object eval(String code) { - final Source source = sourceManager.get("(eval)", code); - return execute(this, source, RubyParser.ParserContext.TOP_LEVEL, coreLibrary.getMainObject(), null); - } - - public Object eval(String code, RubyModule module) { - final Source source = sourceManager.get("(eval)", code); - return execute(this, source, RubyParser.ParserContext.MODULE, module, null); - } - - public Object eval(String code, RubyBinding binding) { - final Source source = sourceManager.get("(eval)", code); - return execute(this, source, RubyParser.ParserContext.TOP_LEVEL, binding.getSelf(), binding.getFrame()); - } - - public void runShell(Node node, MaterializedFrame frame) { - MaterializedFrame existingLocals = frame; - - String prompt = "Ruby> "; - if (node != null) { - final SourceSection src = node.getSourceSection(); - if (src != null) { - prompt = (src.getSource().getName() + ":" + src.getStartLine() + "> "); - } - } - - while (true) { - try { - final String line = configuration.getInputReader().readLine(prompt); - - final ShellResult result = evalShell(line, existingLocals); - - configuration.getStandardOut().println("=> " + result.getResult()); - - existingLocals = result.getFrame(); - } catch (BreakShellException e) { - return; - } catch (Exception e) { - e.printStackTrace(); - } - } - } - - public ShellResult evalShell(String code, MaterializedFrame existingLocals) { - final Source source = sourceManager.get("(shell)", code); - return (ShellResult) execute(this, source, RubyParser.ParserContext.SHELL, coreLibrary.getMainObject(), existingLocals); - } - - public Object execute(RubyContext context, Source source, RubyParser.ParserContext parserContext, Object self, MaterializedFrame parentFrame) { - try { - final RubyParserResult parseResult = parser.parse(context, source, parserContext, parentFrame); - final RubyArguments arguments = new RubyArguments(parentFrame, self, null); - final CallTarget callTarget = Truffle.getRuntime().createCallTarget(parseResult.getRootNode()); - - return callTarget.call(null, arguments); - } catch (RaiseException e) { - throw e; - } catch (ThrowException e) { - throw new RaiseException(context.getCoreLibrary().argumentErrorUncaughtThrow(e.getTag())); - } catch (BreakShellException | QuitException e) { - throw e; - } catch (Throwable e) { - throw new RaiseException(ExceptionTranslator.translateException(this, e)); - } - } - - public long getNextObjectID() { - // TODO(CS): We can theoretically run out of long values - - final long id = nextObjectID.getAndIncrement(); - - if (id < 0) { - nextObjectID.set(Long.MIN_VALUE); - throw new RuntimeException("Object IDs exhausted"); - } - - return id; - } - - public void shutdown() { - atExitManager.run(); - - threadManager.leaveGlobalLock(); - - objectSpaceManager.shutdown(); - - if (fiberManager != null) { - fiberManager.shutdown(); - } - } - - public RubyString makeString(String string) { - return new RubyString(coreLibrary.getStringClass(), string); - } - - public RubyString makeString(char string) { - return makeString(Character.toString(string)); - } - - public Configuration getConfiguration() { - return configuration; - } - - public CoreLibrary getCoreLibrary() { - return coreLibrary; - } - - public FeatureManager getFeatureManager() { - return featureManager; - } - - public ObjectSpaceManager getObjectSpaceManager() { - return objectSpaceManager; - } - - public TraceManager getTraceManager() { - return traceManager; - } - - public FiberManager getFiberManager() { - return fiberManager; - } - - public ThreadManager getThreadManager() { - return threadManager; - } - - public RubyParser getParser() { - return parser; - } - - /** - * Utility method to check if an object should be visible in a Ruby program. Used in assertions - * at method boundaries to check that only values we want to be visible to the programmer become - * so. - */ - public static boolean shouldObjectBeVisible(Object object) { - // TODO(cs): RubyMethod should never be visible - - return object instanceof UndefinedPlaceholder || // - object instanceof Boolean || // - object instanceof Integer || // - object instanceof BigInteger || // - object instanceof Double || // - object instanceof RubyBasicObject || // - object instanceof RubyMethod || // - object instanceof NilPlaceholder || // - object instanceof RubyMethod; - } - - public static boolean shouldObjectsBeVisible(Object... objects) { - for (Object object : objects) { - if (!shouldObjectBeVisible(object)) { - return false; - } - } - - return true; - } - - public void setCurrentDirectory(String currentDirectory) { - this.currentDirectory = currentDirectory; - } - - public String getCurrentDirectory() { - return currentDirectory; - } - - public POSIX getPOSIX() { - return posix; - } - - public AtExitManager getAtExitManager() { - return atExitManager; - } - - public SourceManager getSourceManager() { - return sourceManager; - } - - public RubyDebugManager getRubyDebugManager() { - return rubyDebugManager; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/RubyParser.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/RubyParser.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; - -/** - * Interface to a Ruby parser. - */ -public interface RubyParser { - - public static enum ParserContext { - TOP_LEVEL, SHELL, MODULE - } - - RubyParserResult parse(RubyContext context, Source source, ParserContext parserContext, MaterializedFrame parentFrame); - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/RubyParserResult.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/RubyParserResult.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime; - -import com.oracle.truffle.api.nodes.*; - -/** - * The result of parsing Ruby code is a root node and a frame descriptor for the method in that - * root. The root node will always be a {@code RubyRootNode}, but this package is below the nodes - * package so currently cannot refer to it. - */ -public class RubyParserResult { - - private final RootNode rootNode; - - public RubyParserResult(RootNode rootNode) { - assert rootNode != null; - this.rootNode = rootNode; - } - - public RootNode getRootNode() { - return rootNode; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/ShellResult.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/ShellResult.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime; - -import com.oracle.truffle.api.frame.*; - -/** - * The result of executing a line in a shell is a result value and the final frame containing any - * local variables set. - */ -public class ShellResult { - - private final Object result; - private final MaterializedFrame frame; - - public ShellResult(Object result, MaterializedFrame frame) { - assert RubyContext.shouldObjectBeVisible(result); - assert frame != null; - - this.result = result; - this.frame = frame; - } - - public Object getResult() { - return result; - } - - public MaterializedFrame getFrame() { - return frame; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/UndefinedPlaceholder.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/UndefinedPlaceholder.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime; - -/** - * The {@link UndefinedPlaceholder} is a value that represents an undefined value in Ruby. This is - * used to differentiate between nil and the true absence of a value, such as an argument that has - * not been passed. - */ -public final class UndefinedPlaceholder { - - public static final UndefinedPlaceholder INSTANCE = new UndefinedPlaceholder(); - - private UndefinedPlaceholder() { - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/configuration/Configuration.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/configuration/Configuration.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.configuration; - -import java.io.*; - -import com.oracle.truffle.ruby.runtime.*; - -/** - * Configurable, immutable global parameters for Ruby. - */ -public class Configuration { - - private final String standardLibrary; - - private final boolean verbose; - private final int warningLevel; - private final int taintCheckLevel; - - private final String defaultExternalEncoding; - private final String defaultInternalEncoding; - - private final boolean debug; - private final boolean trace; - private final boolean fullObjectSpace; - - private final boolean printParseTree; - private final boolean printUninitializedCalls; - private final boolean printJavaExceptions; - - private final PrintStream standardOut; - private final InputReader inputReader; - - public Configuration(ConfigurationBuilder builder) { - assert builder != null; - - standardLibrary = builder.getStandardLibrary(); - - verbose = builder.getVerbose(); - warningLevel = builder.getWarningLevel(); - taintCheckLevel = builder.getTaintCheckLevel(); - - defaultExternalEncoding = builder.getDefaultExternalEncoding(); - defaultInternalEncoding = builder.getDefaultInternalEncoding(); - - debug = builder.getDebug(); - trace = builder.getTrace(); - fullObjectSpace = builder.getFullObjectSpace(); - - printParseTree = builder.getPrintParseTree(); - printUninitializedCalls = builder.getPrintUninitializedCalls(); - printJavaExceptions = builder.getPrintJavaExceptions(); - - standardOut = builder.getStandardOut(); - inputReader = builder.getInputReader(); - } - - public String getStandardLibrary() { - return standardLibrary; - } - - public boolean getDebug() { - return debug; - } - - public boolean getVerbose() { - return verbose; - } - - public int getWarningLevel() { - return warningLevel; - } - - public int getTaintCheckLevel() { - return taintCheckLevel; - } - - public String getDefaultExternalEncoding() { - return defaultExternalEncoding; - } - - public String getDefaultInternalEncoding() { - return defaultInternalEncoding; - } - - public boolean getTrace() { - return trace; - } - - public boolean getFullObjectSpace() { - return fullObjectSpace; - } - - public boolean getPrintParseTree() { - return printParseTree; - } - - public boolean getPrintUninitializedCalls() { - return printUninitializedCalls; - } - - public boolean getPrintJavaExceptions() { - return printJavaExceptions; - } - - public PrintStream getStandardOut() { - return standardOut; - } - - public InputReader getInputReader() { - return inputReader; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/configuration/ConfigurationBuilder.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/configuration/ConfigurationBuilder.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,200 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.configuration; - -import java.io.*; - -import com.oracle.truffle.ruby.runtime.*; - -/** - * The mutable counterpart to {@link Configuration}. - */ -public class ConfigurationBuilder { - - /** - * The path of the JRuby packaging of the Ruby standard library within our source tree. - */ - public static final String JRUBY_STDLIB_JAR = "lib/jruby-stdlib-1.7.4.jar"; - - private String standardLibrary = JRUBY_STDLIB_JAR; - - private boolean debug = true; - private boolean verbose = false; - private int warningLevel = 0; - private int taintCheckLevel = 0; - - private String defaultExternalEncoding = null; - private String defaultInternalEncoding = null; - - private boolean trace = true; - private boolean fullObjectSpace = false; - - private boolean printParseTree = false; - private boolean printUninitializedCalls = false; - private boolean printJavaExceptions = false; - - private PrintStream standardOut = System.out; - - private InputReader inputReader = new InputReader() { - - private final BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); - - @Override - public String readLine(String prompt) throws IOException { - System.err.print(prompt); - return reader.readLine(); - } - - }; - - public ConfigurationBuilder() { - } - - public ConfigurationBuilder(Configuration configuration) { - assert configuration != null; - - standardLibrary = configuration.getStandardLibrary(); - - debug = configuration.getDebug(); - verbose = configuration.getVerbose(); - warningLevel = configuration.getWarningLevel(); - taintCheckLevel = configuration.getTaintCheckLevel(); - - defaultExternalEncoding = configuration.getDefaultExternalEncoding(); - defaultInternalEncoding = configuration.getDefaultInternalEncoding(); - - trace = configuration.getTrace(); - fullObjectSpace = configuration.getFullObjectSpace(); - - printParseTree = configuration.getPrintParseTree(); - printUninitializedCalls = configuration.getPrintUninitializedCalls(); - printJavaExceptions = configuration.getPrintJavaExceptions(); - - standardOut = configuration.getStandardOut(); - } - - public String getStandardLibrary() { - return standardLibrary; - } - - public void setStandardLibrary(String standardLibrary) { - assert standardLibrary != null; - this.standardLibrary = standardLibrary; - } - - public boolean getDebug() { - return debug; - } - - public void setDebug(boolean debug) { - this.debug = debug; - } - - public boolean getVerbose() { - return verbose; - } - - public void setVerbose(boolean verbose) { - this.verbose = verbose; - } - - public int getWarningLevel() { - return warningLevel; - } - - public void setWarningLevel(int warningLevel) { - this.warningLevel = warningLevel; - } - - public int getTaintCheckLevel() { - return taintCheckLevel; - } - - public void setTaintCheckLevel(int taintCheckLevel) { - this.taintCheckLevel = taintCheckLevel; - } - - public String getDefaultExternalEncoding() { - return defaultExternalEncoding; - } - - public void setDefaultExternalEncoding(String defaultExternalEncoding) { - assert defaultExternalEncoding != null; - this.defaultExternalEncoding = defaultExternalEncoding; - } - - public String getDefaultInternalEncoding() { - return defaultInternalEncoding; - } - - public void setDefaultInternalEncoding(String defaultInternalEncoding) { - assert defaultInternalEncoding != null; - this.defaultInternalEncoding = defaultInternalEncoding; - } - - public boolean getTrace() { - return trace; - } - - public void setTrace(boolean trace) { - this.trace = trace; - } - - public boolean getFullObjectSpace() { - return fullObjectSpace; - } - - public void setFullObjectSpace(boolean fullObjectSpace) { - this.fullObjectSpace = fullObjectSpace; - } - - public boolean getPrintParseTree() { - return printParseTree; - } - - public void setPrintParseTree(boolean printParseTree) { - this.printParseTree = printParseTree; - } - - public boolean getPrintUninitializedCalls() { - return printUninitializedCalls; - } - - public void setPrintUninitializedCalls(boolean printUninitializedCalls) { - this.printUninitializedCalls = printUninitializedCalls; - } - - public boolean getPrintJavaExceptions() { - return printJavaExceptions; - } - - public void setPrintJavaExceptions(boolean printJavaExceptions) { - this.printJavaExceptions = printJavaExceptions; - } - - public PrintStream getStandardOut() { - return standardOut; - } - - public void setStandardOut(PrintStream standardOut) { - assert standardOut != null; - this.standardOut = standardOut; - } - - public InputReader getInputReader() { - return inputReader; - } - - public void setInputReader(InputReader lineReader) { - assert lineReader != null; - this.inputReader = lineReader; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/control/BreakException.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/control/BreakException.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.control; - -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.runtime.*; - -/** - * Controls a break from a control structure or method. - */ -public final class BreakException extends ControlFlowException { - - public static final BreakException NIL = new BreakException(NilPlaceholder.INSTANCE); - - private final Object result; - - public BreakException(Object result) { - assert RubyContext.shouldObjectBeVisible(result); - - this.result = result; - } - - public Object getResult() { - return result; - } - - private static final long serialVersionUID = -8650123232850256133L; - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/control/BreakShellException.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/control/BreakShellException.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,21 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.control; - -import com.oracle.truffle.api.nodes.*; - -/** - * Controls breaking out of a shell. - */ -public final class BreakShellException extends ControlFlowException { - - private static final long serialVersionUID = 6448983812696841922L; - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/control/ContinuationReturnException.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/control/ContinuationReturnException.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.control; - -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; - -/** - * Controls return from a continuation. - */ -public final class ContinuationReturnException extends ControlFlowException { - - private final RubyContinuation continuation; - private final Object value; - - public ContinuationReturnException(RubyContinuation continuation, Object value) { - assert continuation != null; - assert RubyContext.shouldObjectBeVisible(value); - - this.continuation = continuation; - this.value = value; - } - - /** - * Get the continuation that caused this. - */ - public RubyContinuation getContinuation() { - return continuation; - } - - /** - * Get the value that has been returned. - */ - public Object getValue() { - return value; - } - - private static final long serialVersionUID = 6215834704293311504L; - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/control/ExceptionTranslator.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/control/ExceptionTranslator.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.control; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -public final class ExceptionTranslator { - - /** - * Translate a Java exception into a Ruby exception. - */ - public static RubyBasicObject translateException(RubyContext context, Throwable exception) { - assert context != null; - assert exception != null; - - CompilerAsserts.neverPartOfCompilation(); - - // RaiseException already includes the Ruby exception - - if (exception instanceof RaiseException) { - return ((RaiseException) exception).getRubyException(); - } - - // Translate divide by zero into ZeroDivisionError - - if (exception instanceof ArithmeticException && (exception.getMessage().endsWith("divide by zero") || exception.getMessage().endsWith("/ by zero"))) { - return new RubyException(context.getCoreLibrary().getZeroDivisionErrorClass(), "divided by 0"); - } - - /* - * If we can't translate the exception into a Ruby exception, then the error is ours and we - * report it as as RubyTruffleError. If a programmer sees this then it's a bug in our - * implementation. - */ - - if (context.getConfiguration().getPrintJavaExceptions()) { - exception.printStackTrace(); - } - - String message; - - if (exception.getMessage() == null) { - message = exception.getClass().getSimpleName(); - } else { - message = exception.getMessage(); - } - - return new RubyException(context.getCoreLibrary().getRubyTruffleErrorClass(), message); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/control/NextException.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/control/NextException.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.control; - -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.runtime.*; - -/** - * Controls moving to the next iteration in a control structure or method. - */ -public final class NextException extends ControlFlowException { - - public static final NextException NIL = new NextException(NilPlaceholder.INSTANCE); - - private final Object result; - - public NextException(Object result) { - assert RubyContext.shouldObjectBeVisible(result); - - this.result = result; - } - - public Object getResult() { - return result; - } - - private static final long serialVersionUID = -302759969186731457L; - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/control/QuitException.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/control/QuitException.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,21 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.control; - -import com.oracle.truffle.api.nodes.*; - -/** - * Controls breaking out of all executions and ending Ruby execution. - */ -public final class QuitException extends ControlFlowException { - - private static final long serialVersionUID = -3568511099628564190L; - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/control/RaiseException.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/control/RaiseException.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.control; - -import com.oracle.truffle.ruby.runtime.objects.*; - -/** - * Ruby exceptions are just Ruby objects, so they cannot also be exceptions unless we made all Ruby - * objects exceptions. A simpler approach is to wrap Ruby exceptions in Java exceptions when we want - * to throw them. The error messages match MRI. Note that throwing is different to raising in Ruby, - * which is the reason we have both {@link ThrowException} and {@link RaiseException}. - */ -public class RaiseException extends RuntimeException { - - private final RubyBasicObject rubyException; - - public RaiseException(RubyBasicObject rubyException) { - this.rubyException = rubyException; - } - - @Override - public String toString() { - return rubyException.toString(); - } - - @Override - public String getMessage() { - return rubyException.toString(); - } - - public RubyBasicObject getRubyException() { - return rubyException; - } - - private static final long serialVersionUID = 7501185855599094740L; - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/control/RedoException.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/control/RedoException.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,21 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.control; - -import com.oracle.truffle.api.nodes.*; - -/** - * Controls re-doing an iteration in a control structure or method. - */ -public final class RedoException extends ControlFlowException { - - private static final long serialVersionUID = -4717868827111714052L; - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/control/RetryException.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/control/RetryException.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,21 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.control; - -import com.oracle.truffle.api.nodes.*; - -/** - * Controls re-trying an iteration in a control structure or method. - */ -public final class RetryException extends ControlFlowException { - - private static final long serialVersionUID = -1675586631300635765L; - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/control/ReturnException.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/control/ReturnException.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.control; - -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.runtime.*; - -/** - * Controls an explicit return from a method. - */ -public final class ReturnException extends ControlFlowException { - - private final long returnID; - private final Object value; - - public ReturnException(long returnID, Object value) { - assert RubyContext.shouldObjectBeVisible(value); - - this.returnID = returnID; - this.value = value; - } - - /** - * Return the return ID of this return that identifies where it intends to return to. - */ - public long getReturnID() { - return returnID; - } - - /** - * Get the value that has been returned. - */ - public Object getValue() { - return value; - } - - private static final long serialVersionUID = -9177536212065610691L; - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/control/ThrowException.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/control/ThrowException.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.control; - -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.runtime.*; - -/** - * Controls throwing a value. Note that throwing is different to raising in Ruby, which is the - * reason we have both {@link ThrowException} and {@link RaiseException}. - */ -public class ThrowException extends ControlFlowException { - - private final Object tag; - private final Object value; - - public ThrowException(Object tag, Object value) { - assert tag != null; - assert RubyContext.shouldObjectBeVisible(value); - - this.tag = tag; - this.value = value; - } - - public Object getTag() { - return tag; - } - - public Object getValue() { - return value; - } - - private static final long serialVersionUID = 8693305627979840677L; - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/CoreLibrary.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/CoreLibrary.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,651 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.core; - -import java.io.*; -import java.math.*; -import java.util.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.array.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -public class CoreLibrary { - - public static final String RUBY_VERSION = "2.1.0"; - - private final RubyContext context; - - private RubyClass argumentErrorClass; - private RubyClass arrayClass; - private RubyClass basicObjectClass; - private RubyClass bignumClass; - private RubyClass bindingClass; - private RubyClass classClass; - private RubyClass continuationClass; - private RubyClass dirClass; - private RubyClass exceptionClass; - private RubyClass falseClass; - private RubyClass fiberClass; - private RubyClass fileClass; - private RubyClass fixnumClass; - private RubyClass floatClass; - private RubyClass hashClass; - private RubyClass integerClass; - private RubyClass ioClass; - private RubyClass loadErrorClass; - private RubyClass localJumpErrorClass; - private RubyClass matchDataClass; - private RubyClass moduleClass; - private RubyClass nameErrorClass; - private RubyClass nilClass; - private RubyClass noMethodErrorClass; - private RubyClass numericClass; - private RubyClass objectClass; - private RubyClass procClass; - private RubyClass processClass; - private RubyClass rangeClass; - private RubyClass rangeErrorClass; - private RubyClass regexpClass; - private RubyClass rubyTruffleErrorClass; - private RubyClass runtimeErrorClass; - private RubyClass standardErrorClass; - private RubyClass stringClass; - private RubyClass structClass; - private RubyClass symbolClass; - private RubyClass syntaxErrorClass; - private RubyClass systemCallErrorClass; - private RubyClass systemExitClass; - private RubyClass threadClass; - private RubyClass timeClass; - private RubyClass trueClass; - private RubyClass typeErrorClass; - private RubyClass zeroDivisionErrorClass; - - private RubyModule comparableModule; - private RubyModule configModule; - private RubyModule errnoModule; - private RubyModule kernelModule; - private RubyModule mathModule; - private RubyModule objectSpaceModule; - private RubyModule signalModule; - - private RubyModule debugModule; - private RubyArray argv; - private RubyBasicObject globalVariablesObject; - private RubyBasicObject mainObject; - private RubyFalseClass falseObject; - private RubyNilClass nilObject; - private RubyTrueClass trueObject; - - public CoreLibrary(RubyContext context) { - this.context = context; - } - - public void initialize() { - // Create the cyclic classes and modules - - classClass = new RubyClass.RubyClassClass(context); - basicObjectClass = new RubyClass(context, classClass, null, null, "BasicObject"); - objectClass = new RubyClass(null, basicObjectClass, "Object"); - moduleClass = new RubyModule.RubyModuleClass(context); - - // Close the cycles - - moduleClass.unsafeSetRubyClass(classClass); - classClass.unsafeSetSuperclass(moduleClass); - moduleClass.unsafeSetSuperclass(objectClass); - classClass.unsafeSetRubyClass(classClass); - - // Create all other classes and modules - - numericClass = new RubyClass(null, objectClass, "Numeric"); - integerClass = new RubyClass(null, numericClass, "Integer"); - - exceptionClass = new RubyException.RubyExceptionClass(objectClass, "Exception"); - standardErrorClass = new RubyException.RubyExceptionClass(exceptionClass, "StandardError"); - - ioClass = new RubyClass(null, objectClass, "IO"); - - argumentErrorClass = new RubyException.RubyExceptionClass(standardErrorClass, "ArgumentError"); - arrayClass = new RubyArray.RubyArrayClass(objectClass); - bignumClass = new RubyClass(null, integerClass, "Bignum"); - bindingClass = new RubyClass(null, objectClass, "Binding"); - continuationClass = new RubyClass(null, objectClass, "Continuation"); - comparableModule = new RubyModule(moduleClass, null, "Comparable"); - configModule = new RubyModule(moduleClass, null, "Config"); - debugModule = new RubyModule(moduleClass, null, "Debug"); - dirClass = new RubyClass(null, objectClass, "Dir"); - errnoModule = new RubyModule(moduleClass, null, "Errno"); - falseClass = new RubyClass(null, objectClass, "FalseClass"); - fiberClass = new RubyFiber.RubyFiberClass(objectClass); - fileClass = new RubyClass(null, ioClass, "File"); - fixnumClass = new RubyClass(null, integerClass, "Fixnum"); - floatClass = new RubyClass(null, objectClass, "Float"); - hashClass = new RubyHash.RubyHashClass(objectClass); - kernelModule = new RubyModule(moduleClass, null, "Kernel"); - loadErrorClass = new RubyException.RubyExceptionClass(standardErrorClass, "LoadError"); - localJumpErrorClass = new RubyException.RubyExceptionClass(standardErrorClass, "LocalJumpError"); - matchDataClass = new RubyClass(null, objectClass, "MatchData"); - mathModule = new RubyModule(moduleClass, null, "Math"); - nameErrorClass = new RubyClass(null, standardErrorClass, "NameError"); - nilClass = new RubyClass(null, objectClass, "NilClass"); - noMethodErrorClass = new RubyException.RubyExceptionClass(standardErrorClass, "NoMethodError"); - objectSpaceModule = new RubyModule(moduleClass, null, "ObjectSpace"); - procClass = new RubyProc.RubyProcClass(objectClass); - processClass = new RubyClass(null, objectClass, "Process"); - rangeClass = new RubyClass(null, objectClass, "Range"); - rangeErrorClass = new RubyException.RubyExceptionClass(standardErrorClass, "RangeError"); - regexpClass = new RubyRegexp.RubyRegexpClass(objectClass); - rubyTruffleErrorClass = new RubyException.RubyExceptionClass(standardErrorClass, "RubyTruffleError"); - runtimeErrorClass = new RubyException.RubyExceptionClass(standardErrorClass, "RuntimeError"); - stringClass = new RubyString.RubyStringClass(objectClass); - structClass = new RubyClass(null, ioClass, "Struct"); - signalModule = new RubyModule(moduleClass, null, "Signal"); - symbolClass = new RubyClass(null, objectClass, "Symbol"); - syntaxErrorClass = new RubyException.RubyExceptionClass(standardErrorClass, "SyntaxError"); - systemCallErrorClass = new RubyException.RubyExceptionClass(standardErrorClass, "SystemCallError"); - systemExitClass = new RubyException.RubyExceptionClass(exceptionClass, "SystemExit"); - threadClass = new RubyThread.RubyThreadClass(objectClass); - timeClass = new RubyTime.RubyTimeClass(objectClass); - trueClass = new RubyClass(null, objectClass, "TrueClass"); - typeErrorClass = new RubyException.RubyExceptionClass(standardErrorClass, "TypeError"); - zeroDivisionErrorClass = new RubyException.RubyExceptionClass(standardErrorClass, "ZeroDivisionError"); - - // Includes - - objectClass.include(kernelModule); - - // Set constants - - objectClass.setConstant("RUBY_VERSION", new RubyString(stringClass, RUBY_VERSION)); - objectClass.setConstant("RUBY_PATCHLEVEL", 0); - objectClass.setConstant("RUBY_ENGINE", new RubyString(stringClass, "rubytruffle")); - objectClass.setConstant("RUBY_PLATFORM", new RubyString(stringClass, "jvm")); - - argv = new RubyArray(arrayClass, new ObjectArrayStore()); - objectClass.setConstant("ARGV", argv); - objectClass.setConstant("ENV", getEnv()); - - final RubyHash configHash = new RubyHash(hashClass); - configHash.put(new RubyString(stringClass, "ruby_install_name"), new RubyString(stringClass, "rubytruffle")); - configHash.put(new RubyString(stringClass, "RUBY_INSTALL_NAME"), new RubyString(stringClass, "rubytruffle")); - configHash.put(new RubyString(stringClass, "host_os"), new RubyString(stringClass, "unknown")); - configHash.put(new RubyString(stringClass, "exeext"), new RubyString(stringClass, "")); - configHash.put(new RubyString(stringClass, "EXEEXT"), new RubyString(stringClass, "rubytruffle")); - configModule.setConstant("CONFIG", configHash); - objectClass.setConstant("RbConfig", configModule); - - mathModule.setConstant("PI", Math.PI); - - fileClass.setConstant("SEPARATOR", new RubyString(stringClass, File.separator)); - fileClass.setConstant("Separator", new RubyString(stringClass, File.separator)); - fileClass.setConstant("ALT_SEPARATOR", NilPlaceholder.INSTANCE); - fileClass.setConstant("PATH_SEPARATOR", new RubyString(stringClass, File.pathSeparator)); - fileClass.setConstant("FNM_SYSCASE", 0); - - errnoModule.setConstant("ENOENT", new RubyClass(null, systemCallErrorClass, "ENOENT")); - errnoModule.setConstant("EPERM", new RubyClass(null, systemCallErrorClass, "EPERM")); - errnoModule.setConstant("ENOTEMPTY", new RubyClass(null, systemCallErrorClass, "ENOTEMPTY")); - errnoModule.setConstant("EEXIST", new RubyClass(null, systemCallErrorClass, "EEXIST")); - errnoModule.setConstant("EXDEV", new RubyClass(null, systemCallErrorClass, "EXDEV")); - errnoModule.setConstant("EACCES", new RubyClass(null, systemCallErrorClass, "EACCES")); - - // Add all classes and modules as constants in Object - - final RubyModule[] modules = {argumentErrorClass, // - arrayClass, // - basicObjectClass, // - bignumClass, // - bindingClass, // - classClass, // - continuationClass, // - comparableModule, // - configModule, // - debugModule, // - dirClass, // - errnoModule, // - exceptionClass, // - falseClass, // - fiberClass, // - fileClass, // - fixnumClass, // - floatClass, // - hashClass, // - integerClass, // - ioClass, // - kernelModule, // - loadErrorClass, // - localJumpErrorClass, // - matchDataClass, // - mathModule, // - moduleClass, // - nameErrorClass, // - nilClass, // - noMethodErrorClass, // - numericClass, // - objectClass, // - objectSpaceModule, // - procClass, // - processClass, // - rangeClass, // - rangeErrorClass, // - regexpClass, // - rubyTruffleErrorClass, // - runtimeErrorClass, // - signalModule, // - standardErrorClass, // - stringClass, // - structClass, // - symbolClass, // - syntaxErrorClass, // - systemCallErrorClass, // - systemExitClass, // - threadClass, // - timeClass, // - trueClass, // - typeErrorClass, // - zeroDivisionErrorClass}; - - for (RubyModule module : modules) { - objectClass.setConstant(module.getName(), module); - } - - // Create some key objects - - mainObject = new RubyObject(objectClass); - nilObject = new RubyNilClass(nilClass); - trueObject = new RubyTrueClass(trueClass); - falseObject = new RubyFalseClass(falseClass); - - // Create the globals object - - globalVariablesObject = new RubyBasicObject(objectClass); - globalVariablesObject.switchToPrivateLayout(); - globalVariablesObject.setInstanceVariable("$:", new RubyArray(arrayClass, new ObjectArrayStore())); - } - - public void initializeAfterMethodsAdded() { - bignumClass.getSingletonClass().undefMethod("new"); - falseClass.getSingletonClass().undefMethod("new"); - fixnumClass.getSingletonClass().undefMethod("new"); - floatClass.getSingletonClass().undefMethod("new"); - integerClass.getSingletonClass().undefMethod("new"); - nilClass.getSingletonClass().undefMethod("new"); - numericClass.getSingletonClass().undefMethod("new"); - trueClass.getSingletonClass().undefMethod("new"); - } - - public RubyBasicObject box(Object object) { - assert RubyContext.shouldObjectBeVisible(object); - - // TODO(cs): pool common object instances like small Fixnums? - - if (object instanceof RubyBasicObject) { - return (RubyBasicObject) object; - } - - if (object instanceof Boolean) { - if ((boolean) object) { - return trueObject; - } else { - return falseObject; - } - } - - if (object instanceof Integer) { - return new RubyFixnum(fixnumClass, (int) object); - } - - if (object instanceof BigInteger) { - return new RubyBignum(bignumClass, (BigInteger) object); - } - - if (object instanceof Double) { - return new RubyFloat(floatClass, (double) object); - } - - if (object instanceof NilPlaceholder) { - return nilObject; - } - - CompilerDirectives.transferToInterpreter(); - - throw new UnsupportedOperationException("Don't know how to box " + object.getClass().getName()); - } - - public RubyException runtimeError(String message) { - return new RubyException(runtimeErrorClass, message); - } - - public RubyException frozenError(String className) { - return runtimeError(String.format("can't modify frozen %s", className)); - } - - public RubyException argumentError(String message) { - return new RubyException(argumentErrorClass, message); - } - - public RubyException argumentError(int passed, int required) { - return argumentError(String.format("wrong number of arguments (%d for %d)", passed, required)); - } - - public RubyException argumentErrorUncaughtThrow(Object tag) { - return argumentError(String.format("uncaught throw `%s'", tag)); - } - - public RubyException localJumpError(String message) { - return new RubyException(localJumpErrorClass, message); - } - - public RubyException unexpectedReturn() { - return localJumpError("unexpected return"); - } - - public RubyException typeError(String message) { - return new RubyException(typeErrorClass, message); - } - - public RubyException typeError(String from, String to) { - return typeError(String.format("can't convert %s to %s", from, to)); - } - - public RubyException typeErrorIsNotA(String value, String expectedType) { - return typeError(String.format("%s is not a %s", value, expectedType)); - } - - public RubyException typeErrorNeedsToBe(String name, String expectedType) { - return typeError(String.format("%s needs to be %s", name, expectedType)); - } - - public RubyException rangeError(String message) { - return new RubyException(rangeErrorClass, message); - } - - public RubyException nameError(String message) { - return new RubyException(nameErrorClass, message); - } - - public RubyException nameErrorUninitializedConstant(String name) { - return nameError(String.format("uninitialized constant %s", name)); - } - - public RubyException nameErrorNoMethod(String name, String object) { - return nameError(String.format("undefined local variable or method `%s' for %s", name, object)); - } - - public RubyException nameErrorInstanceNameNotAllowable(String name) { - return nameError(String.format("`%s' is not allowable as an instance variable name", name)); - } - - public RubyException nameErrorUncaughtThrow(Object tag) { - return nameError(String.format("uncaught throw `%s'", tag)); - } - - public RubyException noMethodError(String message) { - return new RubyException(context.getCoreLibrary().getNoMethodErrorClass(), message); - } - - public RubyException noMethodError(String name, String object) { - return noMethodError(String.format("undefined method `%s' for %s", name, object)); - } - - public RubyException loadError(String message) { - return new RubyException(context.getCoreLibrary().getLoadErrorClass(), message); - } - - public RubyException loadErrorCannotLoad(String name) { - return loadError(String.format("cannot load such file -- %s", name)); - } - - public RubyException zeroDivisionError() { - return new RubyException(context.getCoreLibrary().getZeroDivisionErrorClass(), "divided by 0"); - } - - public RubyContext getContext() { - return context; - } - - public RubyClass getArgumentErrorClass() { - return argumentErrorClass; - } - - public RubyClass getArrayClass() { - return arrayClass; - } - - public RubyClass getBasicObjectClass() { - return basicObjectClass; - } - - public RubyClass getBignumClass() { - return bignumClass; - } - - public RubyClass getBindingClass() { - return bindingClass; - } - - public RubyClass getClassClass() { - return classClass; - } - - public RubyModule getComparableClass() { - return comparableModule; - } - - public RubyClass getContinuationClass() { - return continuationClass; - } - - public RubyClass getDirClass() { - return dirClass; - } - - public RubyClass getExceptionClass() { - return exceptionClass; - } - - public RubyClass getFalseClass() { - return falseClass; - } - - public RubyClass getFiberClass() { - return fiberClass; - } - - public RubyClass getFileClass() { - return fileClass; - } - - public RubyClass getFixnumClass() { - return fixnumClass; - } - - public RubyClass getFloatClass() { - return floatClass; - } - - public RubyClass getHashClass() { - return hashClass; - } - - public RubyClass getIntegerClass() { - return integerClass; - } - - public RubyClass getIoClass() { - return ioClass; - } - - public RubyClass getLoadErrorClass() { - return loadErrorClass; - } - - public RubyClass getLocalJumpErrorClass() { - return localJumpErrorClass; - } - - public RubyClass getMatchDataClass() { - return matchDataClass; - } - - public RubyClass getModuleClass() { - return moduleClass; - } - - public RubyClass getNameErrorClass() { - return nameErrorClass; - } - - public RubyClass getNilClass() { - return nilClass; - } - - public RubyClass getNoMethodErrorClass() { - return noMethodErrorClass; - } - - public RubyClass getNumericClass() { - return numericClass; - } - - public RubyClass getObjectClass() { - return objectClass; - } - - public RubyClass getProcClass() { - return procClass; - } - - public RubyClass getProcessClass() { - return processClass; - } - - public RubyClass getRangeClass() { - return rangeClass; - } - - public RubyClass getRangeErrorClass() { - return rangeErrorClass; - } - - public RubyClass getRegexpClass() { - return regexpClass; - } - - public RubyClass getRubyTruffleErrorClass() { - return rubyTruffleErrorClass; - } - - public RubyClass getRuntimeErrorClass() { - return runtimeErrorClass; - } - - public RubyModule getSignalModule() { - return signalModule; - } - - public RubyClass getStandardErrorClass() { - return standardErrorClass; - } - - public RubyClass getStringClass() { - return stringClass; - } - - public RubyClass getStructClass() { - return structClass; - } - - public RubyClass getSymbolClass() { - return symbolClass; - } - - public RubyClass getSyntaxErrorClass() { - return syntaxErrorClass; - } - - public RubyClass getSystemCallErrorClass() { - return systemCallErrorClass; - } - - public RubyClass getThreadClass() { - return threadClass; - } - - public RubyClass getTimeClass() { - return timeClass; - } - - public RubyClass getTrueClass() { - return trueClass; - } - - public RubyClass getTypeErrorClass() { - return typeErrorClass; - } - - public RubyClass getZeroDivisionErrorClass() { - return zeroDivisionErrorClass; - } - - public RubyModule getKernelModule() { - return kernelModule; - } - - public RubyModule getMathModule() { - return mathModule; - } - - public RubyModule getObjectSpaceModule() { - return objectSpaceModule; - } - - public RubyModule getDebugModule() { - return debugModule; - } - - public RubyArray getArgv() { - return argv; - } - - public RubyBasicObject getGlobalVariablesObject() { - return globalVariablesObject; - } - - public RubyBasicObject getMainObject() { - return mainObject; - } - - public RubyFalseClass getFalseObject() { - return falseObject; - } - - public RubyNilClass getNilObject() { - return nilObject; - } - - public RubyTrueClass getTrueObject() { - return trueObject; - } - - public RubyHash getEnv() { - final RubyHash hash = new RubyHash(context.getCoreLibrary().getHashClass()); - - for (Map.Entry variable : System.getenv().entrySet()) { - hash.put(context.makeString(variable.getKey()), context.makeString(variable.getValue())); - } - - return hash; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/GeneralConversions.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/GeneralConversions.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,157 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.core; - -import java.math.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.ruby.runtime.*; - -public class GeneralConversions { - - /** - * Convert a value to a boolean, without doing any lookup. - */ - public static boolean toBoolean(Object value) { - assert value != null; - - if (value instanceof NilPlaceholder) { - return false; - } - - if (value instanceof Boolean) { - return (boolean) value; - } - - if (value instanceof RubyTrueClass) { - return true; - } - - if (value instanceof RubyFalseClass) { - return false; - } - - return true; - } - - /** - * Convert a value to a {@code Fixnum}, without doing any lookup. - */ - public static int toFixnum(Object value) { - assert value != null; - - if (value instanceof NilPlaceholder || value instanceof RubyNilClass) { - return 0; - } - - if (value instanceof Integer) { - return (int) value; - } - - if (value instanceof RubyFixnum) { - return ((RubyFixnum) value).getValue(); - } - - if (value instanceof BigInteger) { - throw new UnsupportedOperationException(); - } - - if (value instanceof RubyBignum) { - throw new UnsupportedOperationException(); - } - - if (value instanceof Double) { - return (int) (double) value; - } - - if (value instanceof RubyFloat) { - return (int) ((RubyFloat) value).getValue(); - } - - CompilerDirectives.transferToInterpreter(); - - throw new UnsupportedOperationException(value.getClass().toString()); - } - - /** - * Convert a value to a {@code Float}, without doing any lookup. - */ - public static double toFloat(Object value) { - assert value != null; - - if (value instanceof NilPlaceholder || value instanceof RubyNilClass) { - return 0; - } - - if (value instanceof Integer) { - return (int) value; - } - - if (value instanceof RubyFixnum) { - return ((RubyFixnum) value).getValue(); - } - - if (value instanceof BigInteger) { - return ((BigInteger) value).doubleValue(); - } - - if (value instanceof RubyBignum) { - return ((RubyBignum) value).getValue().doubleValue(); - } - - if (value instanceof Double) { - return (double) value; - } - - if (value instanceof RubyFloat) { - return ((RubyFloat) value).getValue(); - } - - CompilerDirectives.transferToInterpreter(); - - throw new UnsupportedOperationException(); - } - - /** - * Given a {@link BigInteger} value, produce either a {@code Fixnum} or {@code Bignum} . - */ - public static Object fixnumOrBignum(BigInteger value) { - assert value != null; - - if (value.compareTo(RubyFixnum.MIN_VALUE_BIG) >= 0 && value.compareTo(RubyFixnum.MAX_VALUE_BIG) <= 0) { - return value.intValue(); - } else { - return value; - } - } - - /** - * Given a {@code long} value, produce either a {@code Fixnum} or {@code Bignum} . - */ - public static Object fixnumOrBignum(long value) { - if (value >= RubyFixnum.MIN_VALUE && value <= RubyFixnum.MAX_VALUE) { - return (int) value; - } else { - return BigInteger.valueOf(value); - } - } - - /** - * Given a reference, produce either {@code nil} or the object. . - */ - public static Object instanceOrNil(Object object) { - if (object == null) { - return NilPlaceholder.INSTANCE; - } else { - return object; - } - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyBignum.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyBignum.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.core; - -import java.math.*; - -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.array.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -/** - * Represents the Ruby {@code Bignum} class. - */ -public class RubyBignum extends RubyObject implements Unboxable { - - private final BigInteger value; - - public RubyBignum(RubyClass bignumClass, BigInteger value) { - super(bignumClass); - - assert value != null; - - this.value = value; - } - - public BigInteger getValue() { - return value; - } - - public Object unbox() { - return value; - } - - public static RubyArray divMod(RubyContext context, BigInteger a, BigInteger b) { - final BigInteger[] quotientRemainder = a.divideAndRemainder(b); - - final Object quotient = GeneralConversions.fixnumOrBignum(quotientRemainder[0]); - final Object remainder = GeneralConversions.fixnumOrBignum(quotientRemainder[1]); - - final ObjectImmutablePairArrayStore store = new ObjectImmutablePairArrayStore(quotient, remainder); - return new RubyArray(context.getCoreLibrary().getArrayClass(), store); - } - - @Override - public int hashCode() { - return value.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof RubyBignum)) { - return false; - } - RubyBignum other = (RubyBignum) obj; - if (value == null) { - if (other.value != null) { - return false; - } - } else if (!value.equals(other.value)) { - return false; - } - return true; - } - - @Override - public String toString() { - return value.toString(); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyBinding.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyBinding.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.core; - -import com.oracle.truffle.api.frame.*; - -/** - * Represents the Ruby {@code Binding} class. - */ -public class RubyBinding extends RubyObject { - - private final Object self; - private final MaterializedFrame frame; - - public RubyBinding(RubyClass bindingClass, Object self, MaterializedFrame frame) { - super(bindingClass); - - assert self != null; - assert frame != null; - - this.self = self; - this.frame = frame; - } - - public Object getSelf() { - return self; - } - - public MaterializedFrame getFrame() { - return frame; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyClass.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyClass.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,167 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.core; - -import java.util.*; - -import com.oracle.truffle.api.CompilerDirectives.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.lookup.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -/** - * Represents the Ruby {@code Class} class. Note that most of the functionality you might associate - * with {@code Class} is actually in {@code Module}, implemented by {@link RubyModule}. - */ -public class RubyClass extends RubyModule { - - /** - * The class from which we create the object that is {@code Class}. A subclass of - * {@link RubyClass} so that we can override {@link #newInstance} and allocate a - * {@link RubyClass} rather than a normal {@link RubyBasicObject}. - */ - public static class RubyClassClass extends RubyClass { - - public RubyClassClass(RubyContext context) { - super(context, null, null, null, "Class"); - } - - @Override - public RubyBasicObject newInstance() { - return new RubyClass(null, getContext().getCoreLibrary().getObjectClass(), "(unnamed class)"); - } - - } - - @CompilationFinal private RubyClass superclass; - - // We maintain a list of subclasses so we can notify them when they need to update their layout. - private final Set subClasses = Collections.newSetFromMap(new WeakHashMap()); - - /* - * The layout to use for instances of this class - do not confuse with objectLayout, which is - * the layout for this object - the class. - */ - private ObjectLayout objectLayoutForInstances = null; - - public RubyClass(RubyModule parentModule, RubyClass rubySuperclass, String name) { - this(parentModule, rubySuperclass, name, false); - } - - public RubyClass(RubyModule parentModule, RubyClass rubySuperclass, String name, boolean isSingleton) { - this(rubySuperclass.getContext(), rubySuperclass.getContext().getCoreLibrary().getClassClass(), parentModule, rubySuperclass, name); - - if (!isSingleton) { - getSingletonClass(); - } - } - - /** - * This constructor supports initialization and solves boot-order problems and should not - * normally be used from outside this class. - */ - public RubyClass(RubyContext context, RubyClass classClass, RubyModule parentModule, RubyClass superclass, String name) { - super(context, classClass, parentModule, name); - - if (superclass == null) { - objectLayoutForInstances = ObjectLayout.EMPTY; - } else { - unsafeSetSuperclass(superclass); - } - } - - public RubyClass getSuperclass() { - assert superclass != null; - return superclass; - } - - @Override - public RubyClass getSingletonClass() { - if (rubySingletonClass == null) { - RubyClass singletonSuperclass; - - if (superclass == null) { - singletonSuperclass = getRubyClass(); - } else { - singletonSuperclass = superclass.getSingletonClass(); - } - - rubySingletonClass = new RubyClass(getParentModule(), singletonSuperclass, String.format("#", getName()), true); - - lookupNode = new LookupFork(rubySingletonClass, lookupNode); - } - - return rubySingletonClass; - } - - /** - * This method supports initialization and solves boot-order problems and should not normally be - * used. - */ - public void unsafeSetSuperclass(RubyClass newSuperclass) { - assert superclass == null; - - superclass = newSuperclass; - superclass.addDependent(this); - superclass.subClasses.add(this); - - include(superclass); - - objectLayoutForInstances = new ObjectLayout(getName(), superclass.objectLayoutForInstances); - } - - public RubyBasicObject newInstance() { - return new RubyObject(this); - } - - /** - * Is an instance of this class assignable to some location expecting some other class? - */ - public boolean assignableTo(RubyClass otherClass) { - if (this == otherClass) { - return true; - } - - if (superclass == null) { - return false; - } - - return superclass.assignableTo(otherClass); - } - - /** - * Returns the object layout that objects of this class should use. Do not confuse with - * {@link #getObjectLayout}, which for {@link RubyClass} will return the layout of the class - * object itself. - */ - public ObjectLayout getObjectLayoutForInstances() { - return objectLayoutForInstances; - } - - /** - * Change the layout to be used for instances of this object. - */ - public void setObjectLayoutForInstances(ObjectLayout newObjectLayoutForInstances) { - objectLayoutForInstances = newObjectLayoutForInstances; - - for (RubyClass subClass : subClasses) { - subClass.renewObjectLayoutForInstances(); - } - } - - private void renewObjectLayoutForInstances() { - objectLayoutForInstances = objectLayoutForInstances.renew(superclass.objectLayoutForInstances); - - for (RubyClass subClass : subClasses) { - subClass.renewObjectLayoutForInstances(); - } - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyContinuation.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyContinuation.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.core; - -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.control.*; -import com.oracle.truffle.ruby.runtime.core.array.*; - -/** - * Represents the Ruby {@code Continuation} class. We only support continuations that just move up - * the stack and are one-shot. - */ -public class RubyContinuation extends RubyObject { - - /* - * A continuation is dead if we have already resumed it once. We will not be able to resume it - * again due to the current implementation being an exception thrown to go back up the stack. - */ - private boolean dead = false; - - public RubyContinuation(RubyClass rubyClass) { - super(rubyClass); - } - - /** - * To enter a continuation means to remember the execution state at this point, reify that into - * an object, and then call the passed block. For our implementation, the continuation will be - * dead when this method resumes. - */ - public Object enter(RubyProc block) { - try { - return block.call(null, this); - } catch (ContinuationReturnException e) { - // Thrown in call - - // Check the exception is for this continuation - - if (e.getContinuation() == this) { - return e.getValue(); - } else { - throw e; - } - } finally { - dead = true; - } - } - - /** - * To call a continuation means to go back to the execution state when it was created. For our - * implementation we can only do this once, and only if that means jumping back up the stack. - */ - public void call(Object... args) { - if (dead) { - throw new UnsupportedOperationException("Only continuations that just move up the stack and are one-shot are supported"); - } - - Object returnValue; - - if (args.length == 0) { - returnValue = NilPlaceholder.INSTANCE; - } else if (args.length == 1) { - returnValue = args[0]; - } else { - returnValue = RubyArray.specializedFromObjects(getRubyClass().getContext().getCoreLibrary().getArrayClass(), args); - } - - // Caught in enter - - throw new ContinuationReturnException(this, returnValue); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyException.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyException.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.core; - -import com.oracle.truffle.ruby.runtime.objects.*; - -/** - * Represents the Ruby {@code Exception} class. - */ -public class RubyException extends RubyObject { - - /** - * The class from which we create the object that is {@code Exception}. A subclass of - * {@link RubyClass} so that we can override {@link #newInstance} and allocate a - * {@link RubyException} rather than a normal {@link RubyBasicObject}. - */ - public static class RubyExceptionClass extends RubyClass { - - public RubyExceptionClass(RubyClass superClass, String name) { - super(null, superClass, name); - } - - @Override - public RubyBasicObject newInstance() { - return new RubyException(this); - } - - } - - private RubyString message; - - public RubyException(RubyClass rubyClass) { - super(rubyClass); - message = rubyClass.getContext().makeString("(object uninitialized)"); - } - - public RubyException(RubyClass rubyClass, String message) { - this(rubyClass, rubyClass.getContext().makeString(message)); - } - - public RubyException(RubyClass rubyClass, RubyString message) { - this(rubyClass); - initialize(message); - } - - public void initialize(RubyString setMessage) { - assert setMessage != null; - message = setMessage; - } - - public RubyString getMessage() { - return message; - } - - @Override - public String toString() { - return message.toString(); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyFalseClass.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyFalseClass.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.core; - -import com.oracle.truffle.ruby.runtime.objects.*; - -/** - * Represents the Ruby {@code FalseClass} class. - */ -public class RubyFalseClass extends RubyObject implements Unboxable { - - public RubyFalseClass(RubyClass objectClass) { - super(objectClass); - } - - public Object unbox() { - return false; - } - - @Override - public String toString() { - return "false"; - } - - @Override - public boolean equals(Object other) { - return other instanceof RubyFalseClass || (other instanceof Boolean && !((boolean) other)); - } - - @Override - public int hashCode() { - return Boolean.FALSE.hashCode(); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyFiber.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyFiber.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,173 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.core; - -import java.util.concurrent.*; - -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.array.*; -import com.oracle.truffle.ruby.runtime.objects.*; -import com.oracle.truffle.ruby.runtime.subsystems.*; - -/** - * Represents the Ruby {@code Fiber} class. The current implementation uses Java threads and message - * passing. Note that the relationship between Java threads, Ruby threads and Ruby fibers is - * complex. A Java thread might be running a fiber that on difference resumptions is representing - * different Ruby threads. Take note of the lock contracts on {@link #waitForResume} and - * {@link #resume}. - */ -public class RubyFiber extends RubyObject { - - public static class RubyFiberClass extends RubyClass { - - public RubyFiberClass(RubyClass objectClass) { - super(null, objectClass, "Fiber"); - } - - @Override - public RubyBasicObject newInstance() { - return new RubyFiber(this, getContext().getFiberManager(), getContext().getThreadManager()); - } - - } - - private interface FiberMessage { - } - - private class FiberResumeMessage implements FiberMessage { - - private final RubyThread thread; - private final RubyFiber sendingFiber; - private final Object arg; - - public FiberResumeMessage(RubyThread thread, RubyFiber sendingFiber, Object arg) { - this.thread = thread; - this.sendingFiber = sendingFiber; - this.arg = arg; - } - - public RubyThread getThread() { - return thread; - } - - public RubyFiber getSendingFiber() { - return sendingFiber; - } - - public Object getArg() { - return arg; - } - - } - - private class FiberExitMessage implements FiberMessage { - } - - public class FiberExitException extends ControlFlowException { - - private static final long serialVersionUID = 1522270454305076317L; - - } - - private final FiberManager fiberManager; - private final ThreadManager threadManager; - - private BlockingQueue messageQueue = new ArrayBlockingQueue<>(1); - public RubyFiber lastResumedByFiber = null; - - public RubyFiber(RubyClass rubyClass, FiberManager fiberManager, ThreadManager threadManager) { - super(rubyClass); - this.fiberManager = fiberManager; - this.threadManager = threadManager; - } - - public void initialize(RubyProc block) { - final RubyFiber finalFiber = this; - final RubyProc finalBlock = block; - - new Thread(new Runnable() { - - @Override - public void run() { - fiberManager.registerFiber(finalFiber); - - try { - try { - final Object arg = finalFiber.waitForResume(); - final Object result = finalBlock.call(null, arg); - finalFiber.lastResumedByFiber.resume(finalFiber, result); - } catch (FiberExitException e) { - // Naturally exit the thread on catching this - } - } finally { - fiberManager.unregisterFiber(finalFiber); - } - } - - }).start(); - } - - /** - * Send the Java thread that represents this fiber to sleep until it recieves a resume or exit - * message. On entry, assumes that the GIL is not held. On exit, holding the GIL. - */ - public Object waitForResume() { - FiberMessage message = null; - - do { - try { - // TODO(cs) what is a suitable timeout? - message = messageQueue.poll(1, TimeUnit.SECONDS); - } catch (InterruptedException e) { - // Poll again - } - } while (message == null); - - if (message instanceof FiberExitMessage) { - throw new FiberExitException(); - } - - final FiberResumeMessage resumeMessage = (FiberResumeMessage) message; - - threadManager.enterGlobalLock(resumeMessage.getThread()); - - fiberManager.setCurrentFiber(this); - - lastResumedByFiber = resumeMessage.getSendingFiber(); - return resumeMessage.getArg(); - } - - /** - * Send a message to a fiber by posting into a message queue. Doesn't explicitly notify the Java - * thread (although the queue implementation may) and doesn't wait for the message to be - * received. On entry, assumes the the GIL is held. On exit, not holding the GIL. - */ - public void resume(RubyFiber sendingFiber, Object... args) { - Object arg; - - if (args.length == 0) { - arg = NilPlaceholder.INSTANCE; - } else if (args.length == 1) { - arg = args[0]; - } else { - arg = RubyArray.specializedFromObjects(getRubyClass().getContext().getCoreLibrary().getArrayClass(), args); - } - - final RubyThread runningThread = threadManager.leaveGlobalLock(); - - messageQueue.add(new FiberResumeMessage(runningThread, sendingFiber, arg)); - } - - public void shutdown() { - messageQueue.add(new FiberExitMessage()); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyFile.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyFile.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.core; - -import java.io.*; - -import com.oracle.truffle.ruby.runtime.*; - -/** - * Represents the Ruby {@code File} class. - */ -public class RubyFile extends RubyObject { - - private final Reader reader; - private final Writer writer; - - public RubyFile(RubyClass rubyClass, Reader reader, Writer writer) { - super(rubyClass); - this.reader = reader; - this.writer = writer; - } - - public void close() { - if (reader != null) { - try { - reader.close(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - if (writer != null) { - try { - writer.close(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - } - - public static String expandPath(String fileName) { - // TODO(cs): see the other expandPath - - try { - return new File(fileName).getCanonicalPath(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - public static String expandPath(String fileName, String dir) { - /* - * TODO(cs): this isn't quite correct - I think we want to collapse .., but we don't want to - * resolve symlinks etc. This might be where we want to start borrowing JRuby's - * implementation, but it looks quite tied to their data structures. - */ - - try { - return new File(dir, fileName).getCanonicalPath(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - public static RubyFile open(RubyContext context, String fileName, String mode) { - Reader reader; - Writer writer; - - if (mode.equals("rb")) { - try { - reader = new InputStreamReader(new FileInputStream(fileName)); - } catch (FileNotFoundException e) { - throw new RuntimeException(e); - } - - writer = null; - } else if (mode.equals("w")) { - reader = null; - - try { - writer = new OutputStreamWriter(new FileOutputStream(fileName)); - } catch (FileNotFoundException e) { - throw new RuntimeException(e); - } - } else { - throw new UnsupportedOperationException(); - } - - final RubyFile file = new RubyFile(context.getCoreLibrary().getFileClass(), reader, writer); - - return file; - } - - public Reader getReader() { - return reader; - } - - public Writer getWriter() { - return writer; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyFixnum.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyFixnum.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.core; - -import java.math.*; - -import com.oracle.truffle.ruby.runtime.objects.*; - -/** - * Represents the Ruby {@code Fixnum} class. - */ -public class RubyFixnum extends RubyObject implements Unboxable { - - public static final int MIN_VALUE = Integer.MIN_VALUE; - public static final int MAX_VALUE = Integer.MAX_VALUE; - - public static final BigInteger MIN_VALUE_BIG = BigInteger.valueOf(MIN_VALUE); - public static final BigInteger MAX_VALUE_BIG = BigInteger.valueOf(MAX_VALUE); - - public static final int SIZE = Integer.SIZE; - - private final int value; - - public RubyFixnum(RubyClass fixnumClass, int value) { - super(fixnumClass); - this.value = value; - } - - public int getValue() { - return value; - } - - @Override - public String toString() { - return Integer.toString(value); - } - - @Override - public boolean equals(Object other) { - if (other instanceof Integer) { - return value == (int) other; - } else if (other instanceof RubyFixnum) { - return value == ((RubyFixnum) other).value; - } else if (other instanceof BigInteger) { - return ((BigInteger) other).equals(value); - } else if (other instanceof RubyBignum) { - return ((RubyBignum) other).getValue().equals(value); - } else if (other instanceof Double) { - return value == (double) other; - } else if (other instanceof RubyFloat) { - return value == ((RubyFloat) other).getValue(); - } else { - return super.equals(other); - } - } - - @Override - public int hashCode() { - throw new UnsupportedOperationException(); - } - - public Object unbox() { - return value; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyFloat.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyFloat.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.core; - -import com.oracle.truffle.ruby.runtime.objects.*; - -/** - * Represents the Ruby {@code Float} class. - */ -public class RubyFloat extends RubyObject implements Unboxable { - - private final double value; - - public RubyFloat(RubyClass floatClass, double value) { - super(floatClass); - this.value = value; - } - - public double getValue() { - return value; - } - - @Override - public String toString() { - return Double.toString(value); - } - - @Override - public boolean equals(Object other) { - if (other instanceof Integer) { - return value == (int) other; - } else if (other instanceof RubyFixnum) { - return value == ((RubyFixnum) other).getValue(); - } else if (other instanceof Double) { - return value == (double) other; - } else if (other instanceof RubyFloat) { - return value == ((RubyFloat) other).value; - } else { - return super.equals(other); - } - } - - @Override - public int hashCode() { - throw new UnsupportedOperationException(); - } - - public Object unbox() { - return value; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyHash.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyHash.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,127 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.core; - -import java.util.*; - -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; -import com.oracle.truffle.ruby.runtime.objects.*; - -/** - * Represents the Ruby {@code Hash} class. - */ -public class RubyHash extends RubyObject { - - /** - * The class from which we create the object that is {@code Hash}. A subclass of - * {@link RubyClass} so that we can override {@link #newInstance} and allocate a - * {@link RubyHash} rather than a normal {@link RubyBasicObject}. - */ - public static class RubyHashClass extends RubyClass { - - public RubyHashClass(RubyClass objectClass) { - super(null, objectClass, "Hash"); - } - - @Override - public RubyBasicObject newInstance() { - return new RubyHash(this); - } - - } - - public final Map storage = new LinkedHashMap<>(); - @CompilationFinal public RubyProc defaultBlock = null; - - public RubyHash(RubyClass rubyClass, RubyProc defaultBlock) { - super(rubyClass); - initialize(defaultBlock); - } - - public RubyHash(RubyClass rubyClass) { - super(rubyClass); - } - - public void initialize(RubyProc setDefaultBlock) { - defaultBlock = setDefaultBlock; - } - - @Override - public Object dup() { - final RubyHash newHash = new RubyHash(rubyClass); - newHash.setInstanceVariables(getInstanceVariables()); - newHash.storage.putAll(storage); - return newHash; - } - - public void put(Object key, Object value) { - checkFrozen(); - - storage.put(key, value); - } - - public Object get(Object key) { - return storage.get(key); - } - - public Map getMap() { - return storage; - } - - @Override - public String toString() { - final StringBuilder builder = new StringBuilder(); - builder.append("{"); - - for (Map.Entry entry : storage.entrySet()) { - if (builder.length() > 1) { - builder.append(", "); - } - - builder.append(entry.getKey().toString()); - builder.append("=>"); - builder.append(entry.getValue().toString()); - } - - builder.append("}"); - return builder.toString(); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((storage == null) ? 0 : storage.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof RubyHash)) { - return false; - } - RubyHash other = (RubyHash) obj; - if (storage == null) { - if (other.storage != null) { - return false; - } - } else if (!storage.equals(other.storage)) { - return false; - } - return true; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyMatchData.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyMatchData.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.core; - -/** - * Represents the Ruby {@code MatchData} class. - */ -public class RubyMatchData extends RubyObject { - - private final Object[] values; - - public RubyMatchData(RubyClass rubyClass, Object[] values) { - super(rubyClass); - this.values = values; - } - - public Object[] valuesAt(int... indices) { - final Object[] result = new Object[indices.length]; - - for (int n = 0; n < indices.length; n++) { - result[n] = values[indices[n]]; - } - - return result; - } - - public Object[] getValues() { - return values; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyModule.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyModule.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,381 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.core; - -import java.util.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.api.utilities.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.lookup.*; -import com.oracle.truffle.ruby.runtime.methods.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -/** - * Represents the Ruby {@code Module} class. - */ -public class RubyModule extends RubyObject implements LookupNode { - - /** - * The class from which we create the object that is {@code Module}. A subclass of - * {@link RubyClass} so that we can override {@link #newInstance} and allocate a - * {@link RubyModule} rather than a normal {@link RubyBasicObject}. - */ - public static class RubyModuleClass extends RubyClass { - - public RubyModuleClass(RubyContext context) { - super(context, null, null, null, "Module"); - } - - @Override - public RubyBasicObject newInstance() { - return new RubyModule(this, null, "(unnamed module)"); - } - - } - - /** - * The slot within a module definition method frame where we store the implicit state that is - * the current visibility for new methods. - */ - public static final Object VISIBILITY_FRAME_SLOT_ID = new Object(); - - /** - * The slot within a module definition method frame where we store the implicit state that is - * the flag for whether or not new methods will be module methods (functions is the term). - */ - public static final Object MODULE_FUNCTION_FLAG_FRAME_SLOT_ID = new Object(); - - // The context is stored here - objects can obtain it via their class (which is a module) - private final RubyContext context; - - /* - * The module in which this module was defined. By analogy, if superclass is the dynamic scope, - * the parent module is the lexical scope. - */ - private final RubyModule parentModule; - - /* - * The first thing to lookup names in. Not always the class, as we also have singleton classes, - * included modules etc. - */ - private LookupNode lookupParent = LookupTerminal.INSTANCE; - - private final String name; - private final Map methods = new HashMap<>(); - private final Map constants = new HashMap<>(); - private final Map classVariables = new HashMap<>(); - - private final CyclicAssumption unmodifiedAssumption; - - /** - * Keep track of other modules that depend on the configuration of this module in some way. The - * include subclasses and modules that include this module. - */ - private final Set dependents = Collections.newSetFromMap(new WeakHashMap()); - - public RubyModule(RubyClass rubyClass, RubyModule parentModule, String name) { - this(rubyClass.getContext(), rubyClass, parentModule, name); - } - - public RubyModule(RubyContext context, RubyClass rubyClass, RubyModule parentModule, String name) { - super(rubyClass); - - this.context = context; - this.parentModule = parentModule; - this.name = name; - - unmodifiedAssumption = new CyclicAssumption(name + " is unmodified"); - - /* - * Modules always go into the object space manager. Manually allocate an objectID, because - * the lazy mechanism uses the Ruby class of the object, which may not be set yet during - * bootstrap. - */ - - objectID = context.getNextObjectID(); - context.getObjectSpaceManager().add(this); - } - - public RubyModule getParentModule() { - return parentModule; - } - - public void include(RubyModule module) { - checkFrozen(); - - lookupParent = new LookupFork(module, lookupParent); - newVersion(); - module.addDependent(this); - } - - /** - * Set the value of a constant, possibly redefining it. - */ - public void setConstant(String constantName, Object value) { - assert RubyContext.shouldObjectBeVisible(value); - - checkFrozen(); - - getConstants().put(constantName, value); - newVersion(); - // TODO(CS): warn when redefining a constant - } - - public void setClassVariable(String variableName, Object value) { - assert RubyContext.shouldObjectBeVisible(value); - - checkFrozen(); - - if (!setClassVariableIfAlreadySet(variableName, value)) { - classVariables.put(variableName, value); - } - } - - public boolean setClassVariableIfAlreadySet(String variableName, Object value) { - assert RubyContext.shouldObjectBeVisible(value); - - checkFrozen(); - - if (lookupParent.setClassVariableIfAlreadySet(variableName, value)) { - return true; - } - - if (classVariables.containsKey(variableName)) { - classVariables.put(variableName, value); - return true; - } - - return false; - } - - public void removeClassVariable(String variableName) { - checkFrozen(); - - classVariables.remove(variableName); - } - - public void setModuleConstant(String constantName, Object value) { - checkFrozen(); - - setConstant(constantName, value); - getSingletonClass().setConstant(constantName, value); - } - - public void addMethod(RubyMethod method) { - checkFrozen(); - getMethods().put(method.getName(), method); - newVersion(); - } - - /** - * Remove a method from this module. - */ - public void removeMethod(String methodName) { - checkFrozen(); - - getMethods().remove(methodName); - newVersion(); - } - - public void undefMethod(String methodName) { - undefMethod(lookupMethod(methodName)); - } - - public void undefMethod(RubyMethod method) { - addMethod(method.undefined()); - } - - /** - * Alias a method. - */ - public void alias(String newName, String oldName) { - final RubyMethod method = lookupMethod(oldName); - - if (method == null) { - CompilerDirectives.transferToInterpreter(); - throw new RuntimeException("Couldn't alias as coudln't find " + oldName); - } - - addMethod(method.withNewName(newName)); - } - - @Override - public Object lookupConstant(String constantName) { - Object value; - - // Look in this module - - value = getConstants().get(constantName); - - if (value != null) { - return value; - } - - // Look in the parent module - - if (parentModule != null) { - value = parentModule.lookupConstant(constantName); - - if (value != null) { - return value; - } - } - - // Look in the lookup parent - - return lookupParent.lookupConstant(constantName); - } - - @Override - public Object lookupClassVariable(String variableName) { - // Look in this module - - final Object value = classVariables.get(variableName); - - if (value != null) { - return value; - } - - // Look in the parent - - return lookupParent.lookupClassVariable(variableName); - } - - public Set getClassVariables() { - final Set classVariablesSet = new HashSet<>(); - - classVariablesSet.addAll(classVariables.keySet()); - classVariablesSet.addAll(lookupParent.getClassVariables()); - - return classVariablesSet; - } - - @Override - public RubyMethod lookupMethod(String methodName) { - // Look in this module - - final RubyMethod method = getMethods().get(methodName); - - if (method != null) { - return method; - } - - // Look in the parent - - return lookupParent.lookupMethod(methodName); - } - - public void appendFeatures(RubyModule other) { - // TODO(CS): check only run once - - for (Map.Entry constantEntry : getConstants().entrySet()) { - final String constantName = constantEntry.getKey(); - final Object constantValue = constantEntry.getValue(); - other.setModuleConstant(constantName, constantValue); - } - - for (Map.Entry methodEntry : getMethods().entrySet()) { - final String methodName = methodEntry.getKey(); - final RubyMethod method = methodEntry.getValue(); - other.addMethod(method.withNewName(methodName)); - } - } - - public RubyContext getContext() { - return context; - } - - public String getName() { - return name; - } - - @Override - public int hashCode() { - return name.hashCode(); - } - - @Override - public String toString() { - return name; - } - - public void newVersion() { - unmodifiedAssumption.invalidate(); - - // Make dependents new versions - - for (RubyModule dependent : dependents) { - dependent.newVersion(); - } - } - - public void addDependent(RubyModule dependent) { - dependents.add(dependent); - } - - public Assumption getUnmodifiedAssumption() { - return unmodifiedAssumption.getAssumption(); - } - - public void getMethods(Map foundMethods) { - lookupParent.getMethods(foundMethods); - - for (RubyMethod method : methods.values()) { - foundMethods.put(method.getName(), method); - } - } - - public static void setCurrentVisibility(Frame frame, Visibility visibility) { - final FrameSlot slot = frame.getFrameDescriptor().findFrameSlot(VISIBILITY_FRAME_SLOT_ID); - - frame.setObject(slot, visibility); - } - - public void visibilityMethod(PackedFrame frame, Object[] arguments, Visibility visibility) { - if (arguments.length == 0) { - setCurrentVisibility(frame.unpack(), visibility); - } else { - for (Object arg : arguments) { - final RubyMethod method = lookupMethod(arg.toString()); - - if (method == null) { - throw new RuntimeException("Couldn't find method " + arg.toString()); - } - - /* - * If the method was already defined in this class, that's fine {@link addMethod} - * will overwrite it, otherwise we do actually want to add a copy of the method with - * a different visibility to this module. - */ - - addMethod(method.withNewVisibility(visibility)); - } - } - } - - public List getDeclaredMethods() { - return new ArrayList<>(getMethods().values()); - } - - public void moduleEval(String source) { - getRubyClass().getContext().eval(source, this); - } - - public Map getConstants() { - return constants; - } - - public Map getMethods() { - return methods; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyNilClass.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyNilClass.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.core; - -import com.oracle.truffle.ruby.runtime.*; - -/** - * Represents the Ruby {@code NilClass} class. - */ -public class RubyNilClass extends RubyObject { - - public RubyNilClass(RubyClass rubyClass) { - super(rubyClass); - } - - @Override - public boolean equals(Object other) { - return other instanceof RubyNilClass || other instanceof NilPlaceholder; - } - - @Override - public int hashCode() { - return 0; - } - - public static boolean isNil(Object block) { - return block instanceof NilPlaceholder || block instanceof RubyNilClass; - } - - @Override - public String toString() { - return ""; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyObject.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyObject.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.core; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.control.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -/** - * Represents the Ruby {@code Object} class. - */ -public class RubyObject extends RubyBasicObject { - - public boolean frozen = false; - - public RubyObject(RubyClass rubyClass) { - super(rubyClass); - } - - public void checkFrozen() { - if (frozen) { - CompilerDirectives.transferToInterpreter(); - throw new RaiseException(getRubyClass().getContext().getCoreLibrary().frozenError(getRubyClass().getName().toLowerCase())); - } - } - - public Object dup() { - final RubyObject newObject = new RubyObject(rubyClass); - newObject.setInstanceVariables(getInstanceVariables()); - return newObject; - } - - public static String checkInstanceVariableName(RubyContext context, String name) { - if (!name.startsWith("@")) { - throw new RaiseException(context.getCoreLibrary().nameErrorInstanceNameNotAllowable(name)); - } - - return name.substring(1); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyProc.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyProc.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.core; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.control.*; -import com.oracle.truffle.ruby.runtime.methods.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -/** - * Represents the Ruby {@code Proc} class. - */ -public class RubyProc extends RubyObject { - - /** - * The class from which we create the object that is {@code Proc}. A subclass of - * {@link RubyClass} so that we can override {@link #newInstance} and allocate a - * {@link RubyProc} rather than a normal {@link RubyBasicObject}. - */ - public static class RubyProcClass extends RubyClass { - - public RubyProcClass(RubyClass objectClass) { - super(null, objectClass, "Proc"); - } - - @Override - public RubyBasicObject newInstance() { - return new RubyProc(this); - } - - } - - public static enum Type { - PROC, LAMBDA - } - - @CompilationFinal private Type type; - @CompilationFinal private Object self; - @CompilationFinal private RubyProc block; - @CompilationFinal private RubyMethod method; - - public RubyProc(RubyClass procClass) { - super(procClass); - } - - public RubyProc(RubyClass procClass, Type type, Object self, RubyProc block, RubyMethod method) { - super(procClass); - initialize(type, self, block, method); - } - - public void initialize(Type setType, Object setSelf, RubyProc setBlock, RubyMethod setMethod) { - assert setSelf != null; - assert RubyContext.shouldObjectBeVisible(setSelf); - type = setType; - self = setSelf; - block = setBlock; - method = setMethod; - } - - public Object getSelf() { - return self; - } - - @CompilerDirectives.SlowPath - public Object call(PackedFrame caller, Object... args) { - return callWithModifiedSelf(caller, self, args); - } - - public Object callWithModifiedSelf(PackedFrame caller, Object modifiedSelf, Object... args) { - assert modifiedSelf != null; - - try { - return method.call(caller, modifiedSelf, block, args); - } catch (ReturnException e) { - switch (type) { - case PROC: - throw e; - case LAMBDA: - return e.getValue(); - default: - throw new IllegalStateException(); - } - } - } - - public RubyMethod getMethod() { - return method; - } - - public Type getType() { - return type; - } - - public RubyProc getBlock() { - return block; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyRegexp.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyRegexp.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,144 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.core; - -import java.util.regex.*; - -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -/** - * Represents the Ruby {@code Regexp} class. - */ -public class RubyRegexp extends RubyObject { - - /** - * The class from which we create the object that is {@code Regexp}. A subclass of - * {@link RubyClass} so that we can override {@link #newInstance} and allocate a - * {@link RubyRegexp} rather than a normal {@link RubyBasicObject}. - */ - public static class RubyRegexpClass extends RubyClass { - - public RubyRegexpClass(RubyClass objectClass) { - super(null, objectClass, "Regexp"); - } - - @Override - public RubyBasicObject newInstance() { - return new RubyRegexp(getContext().getCoreLibrary().getRegexpClass()); - } - - } - - @CompilationFinal private Pattern pattern; - - public RubyRegexp(RubyClass regexpClass) { - super(regexpClass); - } - - public RubyRegexp(RubyClass regexpClass, String pattern) { - this(regexpClass); - initialize(compile(pattern)); - } - - public RubyRegexp(RubyClass regexpClass, Pattern pattern) { - this(regexpClass); - initialize(pattern); - } - - public void initialize(String setPattern) { - pattern = compile(setPattern); - } - - public void initialize(Pattern setPattern) { - pattern = setPattern; - } - - public Object matchOperator(Frame frame, String string) { - final RubyContext context = getRubyClass().getContext(); - - final Matcher matcher = pattern.matcher(string); - - if (matcher.find()) { - for (int n = 1; n < matcher.groupCount() + 1; n++) { - final FrameSlot slot = frame.getFrameDescriptor().findFrameSlot("$" + n); - - if (slot != null) { - frame.setObject(slot, context.makeString(matcher.group(n))); - } - } - - return matcher.start(); - } else { - return NilPlaceholder.INSTANCE; - } - } - - public Pattern getPattern() { - return pattern; - } - - public Object match(String string) { - final RubyContext context = getRubyClass().getContext(); - - final Matcher matcher = pattern.matcher(string); - - if (!matcher.find()) { - return NilPlaceholder.INSTANCE; - } - - final Object[] values = new Object[matcher.groupCount() + 1]; - - for (int n = 0; n < matcher.groupCount() + 1; n++) { - final String group = matcher.group(n); - - if (group == null) { - values[n] = NilPlaceholder.INSTANCE; - } else { - values[n] = context.makeString(group); - } - } - - return new RubyMatchData(context.getCoreLibrary().getMatchDataClass(), values); - } - - @Override - public int hashCode() { - return pattern.pattern().hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof RubyRegexp)) { - return false; - } - RubyRegexp other = (RubyRegexp) obj; - if (pattern == null) { - if (other.pattern != null) { - return false; - } - } else if (!pattern.pattern().equals(other.pattern.pattern())) { - return false; - } - return true; - } - - public static Pattern compile(String pattern) { - return Pattern.compile(pattern, Pattern.MULTILINE | Pattern.UNIX_LINES); - } -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyString.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyString.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,291 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.core; - -import java.math.*; -import java.nio.*; -import java.nio.charset.*; -import java.util.*; -import java.util.regex.*; - -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.array.*; -import com.oracle.truffle.ruby.runtime.core.range.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -/** - * Represents the Ruby {@code String} class. - */ -public class RubyString extends RubyObject { - - /** - * The class from which we create the object that is {@code String}. A subclass of - * {@link RubyClass} so that we can override {@link #newInstance} and allocate a - * {@link RubyString} rather than a normal {@link RubyBasicObject}. - */ - public static class RubyStringClass extends RubyClass { - - public RubyStringClass(RubyClass objectClass) { - super(null, objectClass, "String"); - } - - @Override - public RubyBasicObject newInstance() { - return new RubyString(getContext().getCoreLibrary().getStringClass(), ""); - } - - } - - private boolean fromJavaString; - - private Charset encoding; - private byte[] bytes; - - private String cachedStringValue; - - /** - * Construct a string from a Java {@link String}, lazily converting to bytes as needed. - */ - public RubyString(RubyClass stringClass, String value) { - super(stringClass); - fromJavaString = true; - encoding = null; - bytes = null; - cachedStringValue = value; - } - - /** - * Construct a string from bytes representing characters in an encoding, lazily converting to a - * Java {@link String} as needed. - */ - public RubyString(RubyClass stringClass, Charset encoding, byte[] bytes) { - super(stringClass); - fromJavaString = false; - this.encoding = encoding; - this.bytes = bytes; - cachedStringValue = null; - } - - public RubyString(RubyString copyOf) { - super(copyOf.getRubyClass().getContext().getCoreLibrary().getStringClass()); - fromJavaString = copyOf.fromJavaString; - encoding = copyOf.encoding; - - if (copyOf.bytes != null) { - bytes = Arrays.copyOf(copyOf.bytes, copyOf.bytes.length); - } else { - bytes = null; - } - - cachedStringValue = copyOf.cachedStringValue; - } - - public boolean isFromJavaString() { - return fromJavaString; - } - - public byte[] getBytes() { - return bytes; - } - - public void replace(String value) { - fromJavaString = true; - encoding = null; - bytes = null; - cachedStringValue = value; - } - - @Override - public String toString() { - if (cachedStringValue == null) { - cachedStringValue = encoding.decode(ByteBuffer.wrap(bytes)).toString(); - } - - return cachedStringValue; - } - - @Override - public boolean equals(Object other) { - if (other == null) { - return false; - } - - // If the other value is a Java string, use our Java string representation to compare - - if (other instanceof String) { - return toString().equals(other); - } - - if (other instanceof RubyString) { - final RubyString otherString = (RubyString) other; - - // If we both came from Java strings, use them to compare - - if (fromJavaString && otherString.fromJavaString) { - return toString().equals(other.toString()); - } - - // If we both have the same encoding, compare bytes - - if (encoding == otherString.encoding) { - return Arrays.equals(bytes, otherString.bytes); - } - - // If we don't have the same encoding, we need some more advanced logic - - throw new UnsupportedOperationException("Can't compare strings in different encodings yet"); - } - - return false; - } - - @Override - public int hashCode() { - return toString().hashCode(); - } - - public static Object getIndex(RubyContext context, String string, Object[] args) { - if (args.length == 1) { - final Object index = args[0]; - - if (index instanceof Integer) { - final int stringLength = string.length(); - final int normalisedIndex = ArrayUtilities.normaliseIndex(stringLength, (int) index); - - return context.makeString(string.charAt(normalisedIndex)); - } else if (index instanceof FixnumRange) { - final FixnumRange range = (FixnumRange) index; - - final int stringLength = string.length(); - - if (range.doesExcludeEnd()) { - final int begin = ArrayUtilities.normaliseIndex(stringLength, range.getBegin()); - final int exclusiveEnd = ArrayUtilities.normaliseExclusiveIndex(stringLength, range.getExclusiveEnd()); - return context.makeString(string.substring(begin, exclusiveEnd)); - } else { - final int begin = ArrayUtilities.normaliseIndex(stringLength, range.getBegin()); - final int inclusiveEnd = ArrayUtilities.normaliseIndex(stringLength, range.getInclusiveEnd()); - return context.makeString(string.substring(begin, inclusiveEnd + 1)); - } - } else { - throw new UnsupportedOperationException("Don't know how to index a string with " + index.getClass()); - } - } else { - final int rangeStart = (int) args[0]; - int rangeLength = (int) args[1]; - - if (rangeLength > string.length() - rangeStart) { - rangeLength = string.length() - rangeStart; - } - - if (rangeStart > string.length()) { - return NilPlaceholder.INSTANCE; - } - - return context.makeString(string.substring(rangeStart, rangeStart + rangeLength)); - } - } - - @Override - public Object dup() { - return new RubyString(this); - } - - public void concat(RubyString other) { - if (fromJavaString && other.fromJavaString) { - cachedStringValue += other.cachedStringValue; - encoding = null; - bytes = null; - } else { - throw new UnsupportedOperationException("Don't know how to append strings with encodings"); - } - } - - public static String ljust(String string, int length, String padding) { - final StringBuilder builder = new StringBuilder(); - - builder.append(string); - - int n = 0; - - while (builder.length() < length) { - builder.append(padding.charAt(n)); - - n++; - - if (n == padding.length()) { - n = 0; - } - } - - return builder.toString(); - } - - public static String rjust(String string, int length, String padding) { - final StringBuilder builder = new StringBuilder(); - - int n = 0; - - while (builder.length() + string.length() < length) { - builder.append(padding.charAt(n)); - - n++; - - if (n == padding.length()) { - n = 0; - } - } - - builder.append(string); - - return builder.toString(); - } - - public static RubyArray scan(RubyContext context, String string, Pattern pattern) { - final Matcher matcher = pattern.matcher(string); - - final RubyArray results = new RubyArray(context.getCoreLibrary().getArrayClass()); - - while (matcher.find()) { - if (matcher.groupCount() == 0) { - results.push(context.makeString(matcher.group(0))); - } else { - final RubyArray subResults = new RubyArray(context.getCoreLibrary().getArrayClass()); - - for (int n = 1; n < matcher.groupCount() + 1; n++) { - subResults.push(context.makeString(matcher.group(n))); - } - - results.push(subResults); - } - } - - return results; - } - - public Object toInteger() { - if (toString().length() == 0) { - return 0; - } - - try { - final int value = Integer.parseInt(toString()); - - if (value >= RubyFixnum.MIN_VALUE && value <= RubyFixnum.MAX_VALUE) { - return value; - } else { - return BigInteger.valueOf(value); - } - } catch (NumberFormatException e) { - return new BigInteger(toString()); - } - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubySymbol.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubySymbol.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.core; - -import java.util.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.methods.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -/** - * Represents the Ruby {@code Symbol} class. - */ -public class RubySymbol extends RubyObject { - - private final String symbol; - - public RubySymbol(RubyClass symbolClass, String symbol) { - super(symbolClass); - this.symbol = symbol.intern(); - } - - public RubyProc toProc() { - final RubyContext context = getRubyClass().getContext(); - - final CallTarget callTarget = new CallTarget() { - - @Override - public Object call(PackedFrame frame, Arguments args) { - final RubyArguments rubyArgs = (RubyArguments) args; - final Object receiver = rubyArgs.getArguments()[0]; - final Object[] sendArgs = Arrays.copyOfRange(rubyArgs.getArguments(), 1, rubyArgs.getArguments().length); - final RubyBasicObject receiverObject = context.getCoreLibrary().box(receiver); - return receiverObject.send(symbol, rubyArgs.getBlock(), sendArgs); - } - - }; - - final CallTargetMethodImplementation methodImplementation = new CallTargetMethodImplementation(callTarget, null); - final RubyMethod method = new RubyMethod(null, null, new UniqueMethodIdentifier(), symbol, null, Visibility.PUBLIC, false, methodImplementation); - - return new RubyProc(context.getCoreLibrary().getProcClass(), RubyProc.Type.PROC, NilPlaceholder.INSTANCE, null, method); - } - - @Override - public String toString() { - return symbol; - } - - @Override - public String inspect() { - return ":" + symbol; - } - - @Override - public int hashCode() { - return symbol.hashCode(); - } - - @Override - public boolean equals(Object other) { - if (other == this) { - return true; - } else if (other instanceof RubySymbol) { - return symbol == ((RubySymbol) other).symbol; - } else if (other instanceof RubyString) { - return other.equals(symbol); - } else { - return super.equals(other); - } - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyThread.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyThread.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,115 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.core; - -import java.util.*; -import java.util.concurrent.*; - -import com.oracle.truffle.ruby.runtime.objects.*; -import com.oracle.truffle.ruby.runtime.subsystems.*; - -/** - * Represents the Ruby {@code Thread} class. Implemented using Java threads, but note that there is - * not a one-to-one mapping between Ruby threads and Java threads - specifically in combination with - * fibers as they are currently implemented as their own Java threads. - */ -public class RubyThread extends RubyObject { - - /** - * The class from which we create the object that is {@code Thread}. A subclass of - * {@link RubyClass} so that we can override {@link #newInstance} and allocate a - * {@link RubyThread} rather than a normal {@link RubyBasicObject}. - */ - public static class RubyThreadClass extends RubyClass { - - public RubyThreadClass(RubyClass objectClass) { - super(null, objectClass, "Thread"); - } - - @Override - public RubyBasicObject newInstance() { - return new RubyThread(this, getContext().getThreadManager()); - } - - } - - private final ThreadManager manager; - - private final CountDownLatch finished = new CountDownLatch(1); - - private final int hashCode = new Random().nextInt(); - - public RubyThread(RubyClass rubyClass, ThreadManager manager) { - super(rubyClass); - this.manager = manager; - } - - public void initialize(RubyProc block) { - final RubyProc finalBlock = block; - - initialize(new Runnable() { - - @Override - public void run() { - finalBlock.call(null); - } - - }); - } - - public void initialize(Runnable runnable) { - final RubyThread finalThread = this; - final Runnable finalRunnable = runnable; - - new Thread(new Runnable() { - - @Override - public void run() { - finalThread.manager.registerThread(finalThread); - finalThread.manager.enterGlobalLock(finalThread); - - try { - finalRunnable.run(); - } finally { - finalThread.manager.leaveGlobalLock(); - finalThread.manager.unregisterThread(finalThread); - finalThread.finished.countDown(); - } - } - - }).start(); - } - - @Override - public int hashCode() { - return hashCode; - } - - public void shutdown() { - } - - public void join() { - final RubyThread runningThread = getRubyClass().getContext().getThreadManager().leaveGlobalLock(); - - try { - while (true) { - try { - finished.await(); - break; - } catch (InterruptedException e) { - // Await again - } - } - } finally { - runningThread.manager.enterGlobalLock(runningThread); - } - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyTime.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyTime.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.core; - -import java.text.*; -import java.util.*; - -import com.oracle.truffle.ruby.runtime.objects.*; - -/** - * Represents the Ruby {@code Time} class. This is a very rough implementation and is only really - * enough to run benchmark harnesses. - */ -public class RubyTime extends RubyObject { - - /** - * The class from which we create the object that is {@code Time}. A subclass of - * {@link RubyClass} so that we can override {@link #newInstance} and allocate a - * {@link RubyTime} rather than a normal {@link RubyBasicObject}. - */ - public static class RubyTimeClass extends RubyClass { - - public RubyTimeClass(RubyClass objectClass) { - super(null, objectClass, "Time"); - } - - @Override - public RubyBasicObject newInstance() { - return new RubyTime(this, milisecondsToNanoseconds(System.currentTimeMillis())); - } - - } - - private final long nanoseconds; - - public RubyTime(RubyClass timeClass, long nanoseconds) { - super(timeClass); - this.nanoseconds = nanoseconds; - } - - /** - * Subtract one time from another, producing duration in seconds. - */ - public double subtract(RubyTime other) { - return nanosecondsToSecond(nanoseconds - other.nanoseconds); - } - - @Override - public String toString() { - /* - * I think this is ISO 8601 with a custom time part. Note that Ruby's time formatting syntax - * is different to Java's. - */ - - return new SimpleDateFormat("Y-MM-d H:m:ss Z").format(toDate()); - } - - private Date toDate() { - return new Date(nanosecondsToMiliseconds(nanoseconds)); - } - - public static RubyTime fromDate(RubyClass timeClass, long timeMiliseconds) { - return new RubyTime(timeClass, milisecondsToNanoseconds(timeMiliseconds)); - } - - private static long milisecondsToNanoseconds(long miliseconds) { - return miliseconds * 1000000; - } - - private static long nanosecondsToMiliseconds(long nanoseconds) { - return nanoseconds / 1000000; - } - - private static double nanosecondsToSecond(long nanoseconds) { - return nanoseconds / 1e9; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyTrueClass.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/RubyTrueClass.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.core; - -import com.oracle.truffle.ruby.runtime.objects.*; - -/** - * Represents the Ruby {@code TrueClass} class. - */ -public class RubyTrueClass extends RubyObject implements Unboxable { - - public RubyTrueClass(RubyClass objectClass) { - super(objectClass); - } - - public Object unbox() { - return true; - } - - @Override - public String toString() { - return "true"; - } - - @Override - public boolean equals(Object other) { - return other instanceof RubyTrueClass || (other instanceof Boolean && (boolean) other); - } - - @Override - public int hashCode() { - return Boolean.TRUE.hashCode(); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/StringFormatter.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/StringFormatter.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,157 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.core; - -import java.io.*; -import java.util.*; - -import com.oracle.truffle.ruby.runtime.core.array.*; - -public class StringFormatter { - - public static String format(String format, List values) { - final ByteArrayOutputStream byteArray = new ByteArrayOutputStream(); - final PrintStream printStream = new PrintStream(byteArray); - - format(printStream, format, values); - - return byteArray.toString(); - } - - public static void format(PrintStream stream, String format, List values) { - /* - * See http://www.ruby-doc.org/core-1.9.3/Kernel.html#method-i-sprintf. - * - * At the moment we just do the basics that we need. We will need a proper lexer later on. - * Or better than that we could compile to Truffle nodes if the format string is constant! I - * don't think we can easily translate to Java's format syntax, otherwise JRuby would do - * that and they don't. - */ - - // I'm not using a for loop, because Checkstyle won't let me modify the control variable - - int n = 0; - int v = 0; - - while (n < format.length()) { - final char c = format.charAt(n); - n++; - - if (c == '%') { - // %[flags][width][.precision]type - - final String flagChars = "0"; - - boolean zeroPad = false; - - while (n < format.length() && flagChars.indexOf(format.charAt(n)) != -1) { - switch (format.charAt(n)) { - case '0': - zeroPad = true; - break; - } - - n++; - } - - int width; - - if (n < format.length() && Character.isDigit(format.charAt(n))) { - final int widthStart = n; - - while (Character.isDigit(format.charAt(n))) { - n++; - } - - width = Integer.parseInt(format.substring(widthStart, n)); - } else { - width = 0; - } - - int precision; - - if (format.charAt(n) == '.') { - n++; - - final int precisionStart = n; - - while (Character.isDigit(format.charAt(n))) { - n++; - } - - precision = Integer.parseInt(format.substring(precisionStart, n)); - } else { - precision = 5; - } - - final char type = format.charAt(n); - n++; - - final StringBuilder formatBuilder = new StringBuilder(); - - formatBuilder.append("%"); - - if (width > 0) { - if (zeroPad) { - formatBuilder.append("0"); - } - - formatBuilder.append(width); - } - - switch (type) { - case 'd': { - formatBuilder.append("d"); - final int value = GeneralConversions.toFixnum(values.get(v)); - stream.printf(formatBuilder.toString(), value); - break; - } - - case 'f': { - formatBuilder.append("."); - formatBuilder.append(precision); - formatBuilder.append("f"); - final double value = GeneralConversions.toFloat(values.get(v)); - stream.printf(formatBuilder.toString(), value); - break; - } - - default: - throw new RuntimeException("Kernel#sprintf error"); - } - - v++; - } else { - stream.print(c); - } - } - } - - public static void formatPuts(PrintStream stream, List args) { - if (args.size() > 0) { - formatPutsInner(stream, args); - } else { - stream.println(); - } - } - - public static void formatPutsInner(PrintStream stream, List args) { - if (args.size() > 0) { - for (Object arg : args) { - if (arg instanceof RubyArray) { - final RubyArray array = (RubyArray) arg; - formatPutsInner(stream, array.asList()); - } else { - stream.println(arg); - } - } - } - } -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/array/ArrayStore.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/array/ArrayStore.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,97 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.core.array; - -/** - * Interface to various ways to store values in arrays. - */ -public interface ArrayStore { - - /** - * Get the size of the store. - */ - int size(); - - /** - * Get a value from the array using a normalized index. - */ - Object get(int normalisedIndex); - - /** - * Get a range of values from an array store. - */ - ArrayStore getRange(int normalisedBegin, int truncatedNormalisedExclusiveEnd); - - /** - * Set a value at an index, or throw {@link GeneraliseArrayStoreException} if that's not - * possible. - */ - void set(int normalisedIndex, Object value) throws GeneraliseArrayStoreException; - - /** - * Set a range to be a single value, or throw {@link GeneraliseArrayStoreException} if that's - * not possible. - */ - void setRangeSingle(int normalisedBegin, int truncatedNormalisedExclusiveEnd, Object value) throws GeneraliseArrayStoreException; - - /** - * Set a range to be a copied from another array, or throw {@link GeneraliseArrayStoreException} - * if that's not possible. - */ - void setRangeArray(int normalisedBegin, int normalisedExclusiveEnd, ArrayStore other) throws GeneraliseArrayStoreException; - - /** - * Insert a value at an index, or throw {@link GeneraliseArrayStoreException} if that's not - * possible. - */ - void insert(int normalisedIndex, Object value) throws GeneraliseArrayStoreException; - - /** - * Push a value onto the end, or throw {@link GeneraliseArrayStoreException} if that's not - * possible. - */ - void push(Object value) throws GeneraliseArrayStoreException; - - /** - * Delete a value at an index, returning the value. - */ - Object deleteAt(int normalisedIndex); - - /** - * Does a store contain a value? - */ - boolean contains(Object value); - - /** - * Duplicate the store. - */ - ArrayStore dup(); - - /** - * Duplicate the store, in a format which can store an object. - */ - ArrayStore generalizeFor(Object type); - - /** - * Get the type of value stored. - */ - Object getIndicativeValue(); - - /** - * Get the contents of the store as a new array. - */ - Object[] toObjectArray(); - - /** - * Does one store equal another. - */ - boolean equals(ArrayStore other); - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/array/ArrayUtilities.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/array/ArrayUtilities.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.core.array; - -/** - * Simple array utilities, not tied to any particular implementation. - */ -public abstract class ArrayUtilities { - - /** - * Apply Ruby's wrap-around index semantics. - */ - public static int normaliseIndex(int length, int index) { - if (index < 0) { - return length + index; - } else { - return index; - } - } - - /** - * Apply Ruby's wrap-around index semantics. - */ - public static int normaliseExclusiveIndex(int length, int exclusiveIndex) { - if (exclusiveIndex < 0) { - return length + exclusiveIndex + 1; - } else { - return exclusiveIndex; - } - } - - /** - * If an exclusive index is beyond the end of the array, truncate it to be length of the array. - */ - public static int truncateNormalisedExclusiveIndex(int length, int normalisedExclusiveEnd) { - return Math.min(length, normalisedExclusiveEnd); - } - - /** - * What capacity should we allocate for a given requested length? - */ - public static int capacityFor(int length) { - return Math.max(16, length * 2); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/array/BaseArrayStore.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/array/BaseArrayStore.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,149 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.core.array; - -/** - * Contains implementations of as much of the array stores that we could easily share. Much of the - * rest depends on static types in method signatures, so is lexically almost the same, but isn't the - * same in type, and as the whole point is to avoid boxing, we can't use Java's generics. - */ -public abstract class BaseArrayStore implements ArrayStore { - - protected int capacity; - protected int size; - - @Override - public int size() { - return size; - } - - /** - * Set a range in the array to be another range. You must ensure that the otherValues array is - * of the same type as your values array. - */ - protected void setRangeArrayMatchingTypes(int normalisedBegin, int normalisedExclusiveEnd, Object otherValues, int otherSize) { - // Is the range the whole array? - - if (normalisedBegin == 0 && normalisedExclusiveEnd == size) { - // Do we already have enough space? - - if (otherSize <= capacity) { - // Copy to our existing array. - final Object values = getValuesArrayObject(); - System.arraycopy(otherValues, 0, values, 0, otherSize); - } else { - // Create a new copy of their array. - setCapacityWithNewArray(otherSize); - final Object values = getValuesArrayObject(); - System.arraycopy(otherValues, 0, values, 0, otherSize); - } - - size = otherSize; - } else { - final int rangeLength = normalisedExclusiveEnd - normalisedBegin; - - // Create extra space - might be negative if the new range is shorter, or zero. - - final int extraSpaceNeeded = otherSize - rangeLength; - - if (extraSpaceNeeded > 0) { - createSpace(normalisedBegin, extraSpaceNeeded); - } else if (extraSpaceNeeded < 0) { - deleteSpace(normalisedBegin, -extraSpaceNeeded); - } - - // Copy across the new values. - final Object values = getValuesArrayObject(); - System.arraycopy(otherValues, 0, values, normalisedBegin, otherSize); - } - } - - protected void createSpace(int normalisedBegin, int count) { - /* - * Is this space at the end or in the middle? - */ - - if (normalisedBegin == size) { - createSpaceAtEnd(count); - } else { - /* - * Create space in the middle - is the array already big enough? - */ - - final int elementsToMove = size - normalisedBegin; - - if (size + count > capacity) { - /* - * The array isn't big enough. We don't want to use Arrays.copyOf because that will - * do wasted copying of the elements we are about to move. However - is - * Arrays.copyOf clever enough to see that only one instance of Array is using the - * block and use realloc, potentially avoiding a malloc and winning? - */ - - final Object values = getValuesArrayObject(); - setCapacityWithNewArray(ArrayUtilities.capacityFor(size + count)); - final Object newValues = getValuesArrayObject(); - System.arraycopy(values, 0, newValues, 0, normalisedBegin); - System.arraycopy(values, normalisedBegin, newValues, normalisedBegin + count, elementsToMove); - } else { - /* - * The array is already big enough - we can copy elements already in the array to - * make space. - */ - - final Object values = getValuesArrayObject(); - System.arraycopy(values, normalisedBegin, values, normalisedBegin + count, elementsToMove); - } - - size += count; - } - } - - protected void createSpaceAtEnd(int count) { - /* - * Create space at the end - we can do this by creating a copy of the array if needed. - */ - - if (size + count > capacity) { - setCapacityByCopying(ArrayUtilities.capacityFor(size + count)); - } - - size += count; - } - - protected void deleteSpace(int normalisedBegin, int count) { - final Object values = getValuesArrayObject(); - final int elementsToMove = size - normalisedBegin - count; - - if (elementsToMove > 0) { - System.arraycopy(values, normalisedBegin + count, values, normalisedBegin, elementsToMove); - } - - size -= count; - } - - protected abstract void setCapacityByCopying(int newCapacity); - - protected abstract void setCapacityWithNewArray(int newCapacity); - - protected abstract Object getValuesArrayObject(); - - @Override - public boolean equals(ArrayStore other) { - for (int n = 0; n < size; n++) { - if (!other.get(n).equals(get(n))) { - return false; - } - } - - return true; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/array/EmptyArrayStore.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/array/EmptyArrayStore.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.core.array; - -import com.oracle.truffle.ruby.runtime.*; - -/** - * An array store that can only be empty. - */ -public final class EmptyArrayStore implements ArrayStore { - - public static final EmptyArrayStore INSTANCE = new EmptyArrayStore(); - - private EmptyArrayStore() { - } - - @Override - public int size() { - return 0; - } - - @Override - public Object get(int normalisedIndex) { - return NilPlaceholder.INSTANCE; - } - - @Override - public ArrayStore getRange(int normalisedBegin, int truncatedNormalisedExclusiveEnd) { - return null; // Represents Nil - } - - @Override - public void set(int normalisedIndex, Object value) throws GeneraliseArrayStoreException { - throw new GeneraliseArrayStoreException(); - } - - @Override - public void setRangeSingle(int normalisedBegin, int truncatedNormalisedExclusiveEnd, Object value) throws GeneraliseArrayStoreException { - throw new GeneraliseArrayStoreException(); - } - - @Override - public void setRangeArray(int normalisedBegin, int normalisedExclusiveEnd, ArrayStore other) throws GeneraliseArrayStoreException { - throw new GeneraliseArrayStoreException(); - } - - @Override - public void insert(int normalisedIndex, Object value) throws GeneraliseArrayStoreException { - throw new GeneraliseArrayStoreException(); - } - - @Override - public void push(Object value) throws GeneraliseArrayStoreException { - throw new GeneraliseArrayStoreException(); - } - - @Override - public Object deleteAt(int normalisedIndex) { - throw new UnsupportedOperationException("Cannot delete from an empty array"); - } - - @Override - public ArrayStore dup() { - return this; - } - - @Override - public boolean contains(Object value) { - return false; - } - - @Override - public ArrayStore generalizeFor(Object type) { - if (type instanceof Integer) { - return new FixnumArrayStore(); - } else { - return new ObjectArrayStore(); - } - } - - @Override - public Object getIndicativeValue() { - return null; - } - - @Override - public Object[] toObjectArray() { - return new Object[]{}; - } - - @Override - public boolean equals(ArrayStore other) { - if (other == null) { - return false; - } else if (other == this) { - return true; - } else { - return other.size() == 0; - } - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/array/FixnumArrayStore.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/array/FixnumArrayStore.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,264 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.core.array; - -import java.util.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.runtime.*; - -/** - * A store for an array of Fixnums. - */ -public final class FixnumArrayStore extends BaseArrayStore { - - private int[] values; - - public FixnumArrayStore() { - this(new int[]{}); - } - - public FixnumArrayStore(int[] values) { - this.values = values; - size = values.length; - capacity = values.length; - } - - @Override - public Object get(int normalisedIndex) { - try { - return getFixnum(normalisedIndex); - } catch (UnexpectedResultException e) { - return e.getResult(); - } - } - - public int getFixnum(int normalisedIndex) throws UnexpectedResultException { - if (normalisedIndex >= size) { - throw new UnexpectedResultException(NilPlaceholder.INSTANCE); - } - - return values[normalisedIndex]; - } - - @Override - public ArrayStore getRange(int normalisedBegin, int truncatedNormalisedExclusiveEnd) { - if (normalisedBegin >= size) { - return null; // Represents Nil - } - - return new FixnumArrayStore(Arrays.copyOfRange(values, normalisedBegin, truncatedNormalisedExclusiveEnd)); - } - - @Override - public void set(int normalisedIndex, Object value) throws GeneraliseArrayStoreException { - if (value instanceof Integer) { - setFixnum(normalisedIndex, (int) value); - } else { - throw new GeneraliseArrayStoreException(); - } - } - - public void setFixnum(int normalisedIndex, int value) throws GeneraliseArrayStoreException { - if (normalisedIndex > size) { - throw new GeneraliseArrayStoreException(); - } - - if (normalisedIndex == size) { - push(value); - } else { - values[normalisedIndex] = value; - } - } - - @Override - public void setRangeSingle(int normalisedBegin, int truncatedNormalisedExclusiveEnd, Object value) throws GeneraliseArrayStoreException { - if (value instanceof Integer) { - setRangeSingleFixnum(normalisedBegin, truncatedNormalisedExclusiveEnd, (int) value); - } else { - throw new GeneraliseArrayStoreException(); - } - } - - public void setRangeSingleFixnum(int normalisedBegin, int truncatedNormalisedExclusiveEnd, int value) { - // Is the range the whole array? - - if (normalisedBegin == 0 && truncatedNormalisedExclusiveEnd == size) { - // Reset length and set the value. - size = 1; - values[0] = value; - } else { - // Delete the range, except for the first value. - deleteSpace(normalisedBegin + 1, truncatedNormalisedExclusiveEnd - normalisedBegin - 1); - - // Set the value we left in. - values[normalisedBegin] = value; - } - } - - @Override - public void setRangeArray(int normalisedBegin, int normalisedExclusiveEnd, ArrayStore other) throws GeneraliseArrayStoreException { - if (other instanceof FixnumArrayStore) { - setRangeArrayFixnum(normalisedBegin, normalisedExclusiveEnd, (FixnumArrayStore) other); - } else { - throw new GeneraliseArrayStoreException(); - } - } - - public void setRangeArrayFixnum(int normalisedBegin, int normalisedExclusiveEnd, FixnumArrayStore other) { - setRangeArrayMatchingTypes(normalisedBegin, normalisedExclusiveEnd, other.values, other.size); - } - - @Override - public void insert(int normalisedIndex, Object value) throws GeneraliseArrayStoreException { - if (value instanceof Integer) { - insertFixnum(normalisedIndex, (int) value); - } else { - throw new GeneraliseArrayStoreException(); - } - } - - public void insertFixnum(int normalisedIndex, int value) throws GeneraliseArrayStoreException { - if (normalisedIndex > size) { - throw new GeneraliseArrayStoreException(); - } - - createSpace(normalisedIndex, 1); - values[normalisedIndex] = value; - } - - @Override - public void push(Object value) throws GeneraliseArrayStoreException { - if (value instanceof Integer) { - pushFixnum((int) value); - } else { - throw new GeneraliseArrayStoreException(); - } - } - - public void pushFixnum(int value) { - createSpaceAtEnd(1); - values[size - 1] = value; - } - - @Override - public Object deleteAt(int normalisedIndex) { - try { - return deleteAtFixnum(normalisedIndex); - } catch (UnexpectedResultException e) { - return e.getResult(); - } - } - - public int deleteAtFixnum(int normalisedIndex) throws UnexpectedResultException { - if (normalisedIndex >= size) { - CompilerDirectives.transferToInterpreter(); - throw new UnexpectedResultException(NilPlaceholder.INSTANCE); - } - - final int value = values[normalisedIndex]; - - deleteSpace(normalisedIndex, 1); - - return value; - } - - @Override - public ArrayStore dup() { - return new FixnumArrayStore(Arrays.copyOf(values, size)); - } - - @Override - public boolean contains(Object value) { - if (!(value instanceof Integer)) { - return false; - } - - final int intValue = (int) value; - - for (int n = 0; n < size; n++) { - if (values[n] == intValue) { - return true; - } - } - - return false; - } - - @Override - public ArrayStore generalizeFor(Object type) { - return new ObjectArrayStore(toObjectArray()); - } - - @Override - public Object getIndicativeValue() { - return 0; - } - - @Override - protected void setCapacityByCopying(int newCapacity) { - values = Arrays.copyOf(values, newCapacity); - capacity = values.length; - } - - @Override - protected void setCapacityWithNewArray(int newCapacity) { - values = new int[newCapacity]; - capacity = values.length; - } - - @Override - protected Object getValuesArrayObject() { - return values; - } - - @Override - public Object[] toObjectArray() { - final Object[] objectValues = new Object[size]; - - // System.arraycopy will not box. - - for (int n = 0; n < size; n++) { - objectValues[n] = values[n]; - } - - return objectValues; - } - - @Override - public boolean equals(ArrayStore other) { - if (other instanceof FixnumArrayStore) { - return equals((FixnumArrayStore) other); - } else { - return super.equals(other); - } - } - - public boolean equals(FixnumArrayStore other) { - if (other == null) { - return false; - } else if (other == this) { - return true; - } else if (other.size != size) { - return false; - } else if (other.capacity == capacity) { - return Arrays.equals(other.values, values); - } else { - for (int n = 0; n < size; n++) { - if (other.values[n] != values[n]) { - return false; - } - } - - return true; - } - } -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/array/FixnumImmutablePairArrayStore.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/array/FixnumImmutablePairArrayStore.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,169 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.core.array; - -import java.util.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.runtime.*; - -/** - * A store for a pair of Fixnums. - */ -public final class FixnumImmutablePairArrayStore extends BaseArrayStore { - - private final int first; - private final int second; - - public FixnumImmutablePairArrayStore(int first, int second) { - size = 2; - capacity = 2; - this.first = first; - this.second = second; - } - - @Override - public int size() { - return 2; - } - - @Override - public Object get(int normalisedIndex) { - switch (normalisedIndex) { - case 0: - return first; - case 1: - return second; - default: - return NilPlaceholder.INSTANCE; - } - } - - public int getFixnum(int normalisedIndex) throws UnexpectedResultException { - switch (normalisedIndex) { - case 0: - return first; - case 1: - return second; - default: - CompilerDirectives.transferToInterpreter(); - throw new UnexpectedResultException(NilPlaceholder.INSTANCE); - } - } - - @Override - public ArrayStore getRange(int normalisedBegin, int truncatedNormalisedExclusiveEnd) { - if (normalisedBegin >= size) { - return null; // Represents Nil - } - - return new FixnumArrayStore(Arrays.copyOfRange(new int[]{first, second}, normalisedBegin, truncatedNormalisedExclusiveEnd)); - } - - @Override - public void set(int normalisedIndex, Object value) throws GeneraliseArrayStoreException { - CompilerDirectives.transferToInterpreter(); - throw new GeneraliseArrayStoreException(); - } - - @Override - public void setRangeSingle(int normalisedBegin, int truncatedNormalisedExclusiveEnd, Object value) throws GeneraliseArrayStoreException { - CompilerDirectives.transferToInterpreter(); - throw new GeneraliseArrayStoreException(); - } - - @Override - public void setRangeArray(int normalisedBegin, int normalisedExclusiveEnd, ArrayStore other) throws GeneraliseArrayStoreException { - CompilerDirectives.transferToInterpreter(); - throw new GeneraliseArrayStoreException(); - } - - @Override - public void insert(int normalisedIndex, Object value) throws GeneraliseArrayStoreException { - CompilerDirectives.transferToInterpreter(); - throw new GeneraliseArrayStoreException(); - } - - @Override - public void push(Object value) throws GeneraliseArrayStoreException { - CompilerDirectives.transferToInterpreter(); - throw new GeneraliseArrayStoreException(); - } - - @Override - public Object deleteAt(int normalisedIndex) { - throw new UnsupportedOperationException(); - } - - @Override - public ArrayStore dup() { - return this; - } - - @Override - public boolean contains(Object value) { - if (value instanceof Integer) { - final int intValue = (int) value; - return first == intValue || second == intValue; - } else { - return false; - } - } - - @Override - public ArrayStore generalizeFor(Object type) { - return new ObjectArrayStore(toObjectArray()); - } - - @Override - public Object getIndicativeValue() { - return 0; - } - - @Override - protected void setCapacityByCopying(int newCapacity) { - throw new UnsupportedOperationException(); - } - - @Override - protected void setCapacityWithNewArray(int newCapacity) { - throw new UnsupportedOperationException(); - } - - @Override - protected Object getValuesArrayObject() { - return new int[]{first, second}; - } - - @Override - public Object[] toObjectArray() { - return new Object[]{first, second}; - } - - @Override - public boolean equals(ArrayStore other) { - if (other instanceof FixnumImmutablePairArrayStore) { - return equals((FixnumImmutablePairArrayStore) other); - } else { - return super.equals(other); - } - } - - public boolean equals(FixnumImmutablePairArrayStore other) { - if (other == null) { - return false; - } else if (other == this) { - return true; - } else { - return other.first == first && other.second == second; - } - } -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/array/GeneraliseArrayStoreException.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/array/GeneraliseArrayStoreException.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,22 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.core.array; - -import com.oracle.truffle.api.nodes.*; - -/** - * An exception that signals that an ArrayStore cannot store a given object because of its type, and - * that the store must be generalized to accommodate it. - */ -public class GeneraliseArrayStoreException extends SlowPathException { - - private static final long serialVersionUID = -7648655548414168177L; - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/array/ObjectArrayStore.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/array/ObjectArrayStore.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,208 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.core.array; - -import java.util.*; - -import com.oracle.truffle.ruby.runtime.*; - -/** - * A store for an array of any objects. - */ -public final class ObjectArrayStore extends BaseArrayStore { - - private Object[] values; - - public ObjectArrayStore() { - this(new Object[]{}); - } - - public ObjectArrayStore(Object[] values) { - this.values = values; - size = values.length; - capacity = values.length; - } - - @Override - public Object get(int normalisedIndex) { - if (normalisedIndex >= size) { - return NilPlaceholder.INSTANCE; - } - - return values[normalisedIndex]; - } - - @Override - public ArrayStore getRange(int normalisedBegin, int normalisedExclusiveEnd) { - if (normalisedBegin >= size) { - return null; // Represents Nil - } - - return new ObjectArrayStore(Arrays.copyOfRange(values, normalisedBegin, normalisedExclusiveEnd)); - } - - @Override - public void set(int normalisedIndex, Object value) throws GeneraliseArrayStoreException { - if (normalisedIndex > size) { - final int originalLength = size; - createSpace(size, normalisedIndex - size + 1); - Arrays.fill(values, originalLength, normalisedIndex, NilPlaceholder.INSTANCE); - values[normalisedIndex] = value; - } else if (normalisedIndex == size) { - push(value); - } else { - values[normalisedIndex] = value; - } - } - - @Override - public void setRangeSingle(int normalisedBegin, int normalisedExclusiveEnd, Object value) throws GeneraliseArrayStoreException { - // Is the range the whole array? - - if (normalisedBegin == 0 && normalisedExclusiveEnd == size) { - // Reset length and set the value. - size = 1; - values[0] = value; - } else { - // Delete the range, except for the first value. - deleteSpace(normalisedBegin + 1, normalisedExclusiveEnd - normalisedBegin - 1); - - // Set the value we left in. - System.err.println(normalisedBegin + " in " + size + " with " + values.length); - values[normalisedBegin] = value; - } - } - - @Override - public void setRangeArray(int normalisedBegin, int normalisedExclusiveEnd, ArrayStore other) throws GeneraliseArrayStoreException { - setRangeArray(normalisedBegin, normalisedExclusiveEnd, (ObjectArrayStore) other.generalizeFor(null)); - } - - public void setRangeArray(int normalisedBegin, int normalisedExclusiveEnd, ObjectArrayStore other) { - setRangeArrayMatchingTypes(normalisedBegin, normalisedExclusiveEnd, other.values, other.size); - } - - @Override - public void insert(int normalisedIndex, Object value) throws GeneraliseArrayStoreException { - if (normalisedIndex > size) { - final int originalLength = size; - createSpaceAtEnd(normalisedIndex - size + 1); - Arrays.fill(values, originalLength, normalisedIndex, NilPlaceholder.INSTANCE); - values[normalisedIndex] = value; - } else { - createSpace(normalisedIndex, 1); - values[normalisedIndex] = value; - } - } - - @Override - public void push(Object value) throws GeneraliseArrayStoreException { - createSpaceAtEnd(1); - values[size - 1] = value; - } - - @Override - public Object deleteAt(int normalisedIndex) { - if (normalisedIndex >= size) { - return NilPlaceholder.INSTANCE; - } - - final Object value = values[normalisedIndex]; - - deleteSpace(normalisedIndex, 1); - - return value; - } - - @Override - public ArrayStore dup() { - return new ObjectArrayStore(Arrays.copyOf(values, size)); - } - - @Override - public boolean contains(Object value) { - for (int n = 0; n < size; n++) { - if (values[n].equals(value)) { - return true; - } - } - - return false; - } - - @Override - public ObjectArrayStore generalizeFor(Object type) { - return this; - } - - @Override - public Object getIndicativeValue() { - return null; - } - - @Override - protected void setCapacityByCopying(int newCapacity) { - values = Arrays.copyOf(values, newCapacity); - capacity = values.length; - } - - @Override - protected void setCapacityWithNewArray(int newCapacity) { - values = new Object[newCapacity]; - capacity = values.length; - } - - @Override - protected Object getValuesArrayObject() { - return values; - } - - public Object[] getValues() { - return values; - } - - @Override - public Object[] toObjectArray() { - if (values.length == size) { - return values; - } else { - return Arrays.copyOf(values, size); - } - } - - @Override - public boolean equals(ArrayStore other) { - if (other instanceof ObjectArrayStore) { - return equals((ObjectArrayStore) other); - } else { - return super.equals(other); - } - } - - public boolean equals(ObjectArrayStore other) { - if (other == null) { - return false; - } else if (other == this) { - return true; - } else if (other.size != size) { - return false; - } else if (other.capacity == capacity) { - return Arrays.equals(other.values, values); - } else { - for (int n = 0; n < size; n++) { - if (!other.values[n].equals(values[n])) { - return false; - } - } - - return true; - } - } -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/array/ObjectImmutablePairArrayStore.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/array/ObjectImmutablePairArrayStore.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,151 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.core.array; - -import java.util.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.ruby.runtime.*; - -/** - * A store for a pair of objects. - */ -public final class ObjectImmutablePairArrayStore extends BaseArrayStore { - - private final Object first; - private final Object second; - - public ObjectImmutablePairArrayStore(Object first, Object second) { - size = 2; - capacity = 2; - this.first = first; - this.second = second; - } - - @Override - public int size() { - return 2; - } - - @Override - public Object get(int normalisedIndex) { - switch (normalisedIndex) { - case 0: - return first; - case 1: - return second; - default: - return NilPlaceholder.INSTANCE; - } - } - - @Override - public ArrayStore getRange(int normalisedBegin, int truncatedNormalisedExclusiveEnd) { - if (normalisedBegin >= size) { - return null; // Represents Nil - } - - return new ObjectArrayStore(Arrays.copyOfRange(new Object[]{first, second}, normalisedBegin, truncatedNormalisedExclusiveEnd)); - } - - @Override - public void set(int normalisedIndex, Object value) throws GeneraliseArrayStoreException { - CompilerDirectives.transferToInterpreter(); - throw new GeneraliseArrayStoreException(); - } - - @Override - public void setRangeSingle(int normalisedBegin, int truncatedNormalisedExclusiveEnd, Object value) throws GeneraliseArrayStoreException { - CompilerDirectives.transferToInterpreter(); - throw new GeneraliseArrayStoreException(); - } - - @Override - public void setRangeArray(int normalisedBegin, int normalisedExclusiveEnd, ArrayStore other) throws GeneraliseArrayStoreException { - CompilerDirectives.transferToInterpreter(); - throw new GeneraliseArrayStoreException(); - } - - @Override - public void insert(int normalisedIndex, Object value) throws GeneraliseArrayStoreException { - CompilerDirectives.transferToInterpreter(); - throw new GeneraliseArrayStoreException(); - } - - @Override - public void push(Object value) throws GeneraliseArrayStoreException { - CompilerDirectives.transferToInterpreter(); - throw new GeneraliseArrayStoreException(); - } - - @Override - public Object deleteAt(int normalisedIndex) { - throw new UnsupportedOperationException(); - } - - @Override - public ArrayStore dup() { - return this; - } - - @Override - public boolean contains(Object value) { - return first.equals(value) || second.equals(value); - } - - @Override - public ArrayStore generalizeFor(Object type) { - return new ObjectArrayStore(toObjectArray()); - } - - @Override - public Object getIndicativeValue() { - return 0; - } - - @Override - protected void setCapacityByCopying(int newCapacity) { - throw new UnsupportedOperationException(); - } - - @Override - protected void setCapacityWithNewArray(int newCapacity) { - throw new UnsupportedOperationException(); - } - - @Override - protected Object getValuesArrayObject() { - return new Object[]{first, second}; - } - - @Override - public Object[] toObjectArray() { - return new Object[]{first, second}; - } - - @Override - public boolean equals(ArrayStore other) { - if (other instanceof ObjectImmutablePairArrayStore) { - return equals((ObjectImmutablePairArrayStore) other); - } else { - return super.equals(other); - } - } - - public boolean equals(ObjectImmutablePairArrayStore other) { - if (other == null) { - return false; - } else if (other == this) { - return true; - } else { - return other.first == first && other.second == second; - } - } -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/array/RubyArray.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/array/RubyArray.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,428 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.core.array; - -import java.util.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; -import com.oracle.truffle.api.CompilerDirectives.SlowPath; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.control.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.methods.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -/** - * Implements the Ruby {@code Array} class. - */ -@SuppressWarnings("unused") -public final class RubyArray extends RubyObject { - - public static class RubyArrayClass extends RubyClass { - - public RubyArrayClass(RubyClass objectClass) { - super(null, objectClass, "Array"); - } - - @Override - public RubyBasicObject newInstance() { - return new RubyArray(this); - } - - } - - @CompilationFinal private ArrayStore store; - - public RubyArray(RubyClass arrayClass) { - this(arrayClass, EmptyArrayStore.INSTANCE); - } - - public RubyArray(RubyClass arrayClass, ArrayStore store) { - super(arrayClass); - this.store = store; - } - - private static RubyArray selfAsArray(Object self) { - if (self instanceof RubyArray) { - return (RubyArray) self; - } else { - throw new IllegalStateException(); - } - } - - @CompilerDirectives.SlowPath - public static RubyArray specializedFromObject(RubyClass arrayClass, Object object) { - ArrayStore store; - - if (object instanceof Integer || object instanceof RubyFixnum) { - store = new FixnumArrayStore(new int[]{GeneralConversions.toFixnum(object)}); - } else { - store = new ObjectArrayStore(new Object[]{object}); - } - - return new RubyArray(arrayClass, store); - } - - /** - * Create a Ruby array from a Java array of objects, choosing the best store. - */ - @CompilerDirectives.SlowPath - public static RubyArray specializedFromObjects(RubyClass arrayClass, Object... objects) { - if (objects.length == 0) { - return new RubyArray(arrayClass); - } - - boolean canUseFixnum = true; - - for (Object object : objects) { - if (!(object instanceof Integer || object instanceof RubyFixnum)) { - canUseFixnum = false; - } - } - - ArrayStore store; - - if (canUseFixnum) { - final int[] values = new int[objects.length]; - - for (int n = 0; n < objects.length; n++) { - values[n] = GeneralConversions.toFixnum(objects[n]); - } - - store = new FixnumArrayStore(values); - } else { - store = new ObjectArrayStore(objects); - } - - return new RubyArray(arrayClass, store); - } - - public Object get(int index) { - return store.get(ArrayUtilities.normaliseIndex(store.size(), index)); - } - - public Object getRangeInclusive(int begin, int inclusiveEnd) { - final int l = store.size(); - final int normalisedInclusiveEnd = ArrayUtilities.normaliseIndex(l, inclusiveEnd); - return getRangeExclusive(begin, normalisedInclusiveEnd + 1); - } - - public Object getRangeExclusive(int begin, int exclusiveEnd) { - final int l = store.size(); - final int normalisedBegin = ArrayUtilities.normaliseIndex(l, begin); - final int truncatedNormalisedExclusiveEnd = ArrayUtilities.truncateNormalisedExclusiveIndex(l, ArrayUtilities.normaliseExclusiveIndex(l, exclusiveEnd)); - - final Object range = store.getRange(normalisedBegin, truncatedNormalisedExclusiveEnd); - - if (range == null) { - return new RubyArray(getRubyClass()); - } else { - return new RubyArray(getRubyClass(), (ArrayStore) range); - } - } - - public void set(int index, Object value) { - checkFrozen(); - - final int l = store.size(); - final int normalisedIndex = ArrayUtilities.normaliseIndex(l, index); - - try { - store.set(normalisedIndex, value); - } catch (GeneraliseArrayStoreException e) { - store = store.generalizeFor(value); - - try { - store.set(normalisedIndex, value); - } catch (GeneraliseArrayStoreException ex) { - throwSecondGeneraliseException(); - } - } - } - - public void setRangeSingleInclusive(int begin, int inclusiveEnd, Object value) { - final int l = store.size(); - final int normalisedInclusiveEnd = ArrayUtilities.normaliseIndex(l, inclusiveEnd); - setRangeSingleExclusive(begin, normalisedInclusiveEnd + 1, value); - } - - public void setRangeSingleExclusive(int begin, int exclusiveEnd, Object value) { - checkFrozen(); - - final int l = store.size(); - final int normalisedBegin = ArrayUtilities.normaliseIndex(l, begin); - final int truncatedNormalisedExclusiveEnd = ArrayUtilities.truncateNormalisedExclusiveIndex(l, ArrayUtilities.normaliseExclusiveIndex(l, exclusiveEnd)); - - try { - store.setRangeSingle(normalisedBegin, truncatedNormalisedExclusiveEnd, value); - } catch (GeneraliseArrayStoreException e) { - store = store.generalizeFor(value); - - try { - store.setRangeSingle(normalisedBegin, truncatedNormalisedExclusiveEnd, value); - } catch (GeneraliseArrayStoreException ex) { - throwSecondGeneraliseException(); - } - } - } - - public void setRangeArrayInclusive(int begin, int inclusiveEnd, RubyArray other) { - final int l = store.size(); - final int normalisedInclusiveEnd = ArrayUtilities.normaliseIndex(l, inclusiveEnd); - setRangeArrayExclusive(begin, normalisedInclusiveEnd + 1, other); - } - - public void setRangeArrayExclusive(int begin, int exclusiveEnd, RubyArray other) { - checkFrozen(); - - final int l = store.size(); - final int normalisedBegin = ArrayUtilities.normaliseIndex(l, begin); - final int normalisedExclusiveEnd = ArrayUtilities.normaliseExclusiveIndex(l, exclusiveEnd); - - try { - store.setRangeArray(normalisedBegin, normalisedExclusiveEnd, other.store); - } catch (GeneraliseArrayStoreException e) { - store = store.generalizeFor(other.store.getIndicativeValue()); - - try { - store.setRangeArray(normalisedBegin, normalisedExclusiveEnd, other.store); - } catch (GeneraliseArrayStoreException ex) { - throwSecondGeneraliseException(); - } - } - } - - public void insert(int index, Object value) { - checkFrozen(); - - final int l = store.size(); - final int normalisedIndex = ArrayUtilities.normaliseIndex(l, index); - - try { - store.insert(normalisedIndex, value); - } catch (GeneraliseArrayStoreException e) { - store = store.generalizeFor(value); - - try { - store.insert(normalisedIndex, value); - } catch (GeneraliseArrayStoreException ex) { - throwSecondGeneraliseException(); - } - } - } - - public void push(Object value) { - checkFrozen(); - - if (store instanceof EmptyArrayStore) { - /* - * Normally we want to transfer to interpreter to generalize an array store, but the - * special case of an empty array is common, will never cause rewrites and has a simple - * implementation, so treat it as a special case. - */ - store = ((EmptyArrayStore) store).generalizeFor(value); - } - - try { - store.push(value); - } catch (GeneraliseArrayStoreException e) { - store = store.generalizeFor(value); - - try { - store.push(value); - } catch (GeneraliseArrayStoreException ex) { - throw new IllegalStateException("Generalised to support a specific value, but value still rejected by store"); - } - } - } - - public void unshift(Object value) { - insert(0, value); - } - - public Object deleteAt(int index) { - checkFrozen(); - - final int l = store.size(); - final int normalisedIndex = ArrayUtilities.normaliseIndex(l, index); - - return store.deleteAt(normalisedIndex); - } - - @Override - @CompilerDirectives.SlowPath - public Object dup() { - return new RubyArray(getRubyClass(), store.dup()); - } - - public ArrayStore getArrayStore() { - return store; - } - - public List asList() { - final RubyArray array = this; - - return new AbstractList() { - - @Override - public Object get(int n) { - return array.get(n); - } - - @Override - public int size() { - return array.size(); - } - - }; - } - - public Object[] toObjectArray() { - return store.toObjectArray(); - } - - private static void throwSecondGeneraliseException() { - CompilerAsserts.neverPartOfCompilation(); - throw new RuntimeException("Generalised based on a value, but the new store also rejected that value."); - } - - public int size() { - return store.size(); - } - - public boolean contains(Object value) { - return store.contains(value); - } - - /** - * Recursive Cartesian product. - *

- * The Array#product method is supposed to be able to take a block, to which it yields tuples as - * they are produced, so it might be worth abstracting this method into sending tuples to some - * interface, which either adds them to an array, or yields them to the block. - */ - @SlowPath - public static RubyArray product(RubyClass arrayClass, RubyArray[] arrays, int l) { - if (arrays.length - l == 1) { - final RubyArray firstArray = arrays[0]; - - final RubyArray tuples = new RubyArray(arrayClass); - - for (int i = 0; i < firstArray.size(); i++) { - final RubyArray tuple = new RubyArray(arrayClass); - tuple.push(firstArray.get(i)); - tuples.push(tuple); - } - - return tuples; - } else { - final RubyArray intermediateTuples = product(arrayClass, arrays, l - 1); - final RubyArray lastArray = arrays[l - 1]; - - final RubyArray tuples = new RubyArray(arrayClass); - - for (int n = 0; n < intermediateTuples.size(); n++) { - for (int i = 0; i < lastArray.size(); i++) { - final RubyArray tuple = (RubyArray) ((RubyArray) intermediateTuples.get(n)).dup(); - tuple.push(lastArray.get(i)); - tuples.push(tuple); - } - } - - return tuples; - } - } - - public boolean equals(RubyArray other) { - if (other == null) { - return false; - } else if (other == this) { - return true; - } else { - return store.equals(other.store); - } - } - - @Override - public boolean equals(Object other) { - if (other instanceof RubyArray) { - return equals((RubyArray) other); - } else { - return false; - } - } - - @Override - public int hashCode() { - getRubyClass().getContext().implementationMessage("Array#hash returns nonsense"); - return 0; - } - - public RubyArray relativeComplement(RubyArray other) { - // TODO(cs): specialize for different stores - - final RubyArray result = new RubyArray(getRubyClass().getContext().getCoreLibrary().getArrayClass()); - - for (Object value : asList()) { - if (!other.contains(value)) { - result.push(value); - } - } - - return result; - } - - public String join(String separator) { - final StringBuilder builder = new StringBuilder(); - - for (int n = 0; n < size(); n++) { - if (n > 0) { - builder.append(separator); - } - - builder.append(get(n).toString()); - } - - return builder.toString(); - } - - public static String join(Object[] parts, String separator) { - final StringBuilder builder = new StringBuilder(); - - for (int n = 0; n < parts.length; n++) { - if (n > 0) { - builder.append(separator); - } - - builder.append(parts[n].toString()); - } - - return builder.toString(); - } - - public void flattenTo(RubyArray result) { - for (int n = 0; n < size(); n++) { - final Object value = get(n); - - if (value instanceof RubyArray) { - ((RubyArray) value).flattenTo(result); - } else { - result.push(value); - } - } - } - - public boolean isEmpty() { - return store.size() == 0; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/range/FixnumRange.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/range/FixnumRange.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,128 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.core.range; - -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.core.array.*; - -/** - * A range that has {@code Fixnum} begin and end. - */ -public class FixnumRange extends RubyRange { - - private final int begin; - private final int end; - private final boolean excludeEnd; - - public FixnumRange(RubyClass rangeClass, int begin, int end, boolean excludeEnd) { - super(rangeClass); - this.begin = begin; - this.end = end; - this.excludeEnd = excludeEnd; - } - - @Override - public String toString() { - if (excludeEnd) { - return begin + "..." + end; - } else { - return begin + ".." + end; - } - } - - @Override - public RubyArray toArray() { - final int length = getLength(); - - if (length < 0) { - return new RubyArray(getRubyClass().getContext().getCoreLibrary().getArrayClass()); - } else { - final int[] values = new int[length]; - - for (int n = 0; n < length; n++) { - values[n] = begin + n; - } - - return new RubyArray(getRubyClass().getContext().getCoreLibrary().getArrayClass(), new FixnumArrayStore(values)); - } - } - - private int getLength() { - if (excludeEnd) { - return end - begin; - } else { - return end - begin + 1; - } - } - - public final int getBegin() { - return begin; - } - - public final int getEnd() { - return end; - } - - public final int getInclusiveEnd() { - if (excludeEnd) { - return end - 1; - } else { - return end; - } - } - - public final int getExclusiveEnd() { - if (excludeEnd) { - return end; - } else { - return end + 1; - } - } - - @Override - public boolean doesExcludeEnd() { - return excludeEnd; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + begin; - result = prime * result + end; - result = prime * result + (excludeEnd ? 1231 : 1237); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof FixnumRange)) { - return false; - } - FixnumRange other = (FixnumRange) obj; - if (begin != other.begin) { - return false; - } - if (end != other.end) { - return false; - } - if (excludeEnd != other.excludeEnd) { - return false; - } - return true; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/range/ObjectRange.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/range/ObjectRange.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.core.range; - -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.core.array.*; - -public class ObjectRange extends RubyRange { - - private final Object begin; - private final Object end; - private final boolean excludeEnd; - - public ObjectRange(RubyClass rangeClass, Object begin, Object end, boolean excludeEnd) { - super(rangeClass); - this.begin = begin; - this.end = end; - this.excludeEnd = excludeEnd; - } - - @Override - public RubyArray toArray() { - throw new UnsupportedOperationException(); - } - - public Object getBegin() { - return begin; - } - - public Object getEnd() { - return end; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((begin == null) ? 0 : begin.hashCode()); - result = prime * result + ((end == null) ? 0 : end.hashCode()); - result = prime * result + (excludeEnd ? 1231 : 1237); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof ObjectRange)) { - return false; - } - ObjectRange other = (ObjectRange) obj; - if (begin == null) { - if (other.begin != null) { - return false; - } - } else if (!begin.equals(other.begin)) { - return false; - } - if (end == null) { - if (other.end != null) { - return false; - } - } else if (!end.equals(other.end)) { - return false; - } - if (excludeEnd != other.excludeEnd) { - return false; - } - return true; - } - - @Override - public boolean doesExcludeEnd() { - // TODO Auto-generated method stub - return false; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/range/RubyRange.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/core/range/RubyRange.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.core.range; - -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.core.array.*; - -public abstract class RubyRange extends RubyObject { - - public RubyRange(RubyClass rangeClass) { - super(rangeClass); - } - - public abstract RubyArray toArray(); - - public abstract boolean doesExcludeEnd(); - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/debug/MethodLocal.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/debug/MethodLocal.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.debug; - -import com.oracle.truffle.ruby.runtime.methods.*; - -/* - * Identifies a local in a method. - */ -public class MethodLocal { - - private final UniqueMethodIdentifier method; - private final String local; - - public MethodLocal(UniqueMethodIdentifier method, String local) { - this.method = method; - this.local = local; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((local == null) ? 0 : local.hashCode()); - result = prime * result + ((method == null) ? 0 : method.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - MethodLocal other = (MethodLocal) obj; - if (local == null) { - if (other.local != null) { - return false; - } - } else if (!local.equals(other.local)) { - return false; - } - if (method == null) { - if (other.method != null) { - return false; - } - } else if (!method.equals(other.method)) { - return false; - } - return true; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/debug/RubyDebugManager.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/debug/RubyDebugManager.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.debug; - -import java.util.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.source.*; -import com.oracle.truffle.api.utilities.*; -import com.oracle.truffle.ruby.runtime.core.*; - -public final class RubyDebugManager { - - private final Map lineAssumptions = new HashMap<>(); - private final Map lineBreakpoints = new HashMap<>(); - - private final Map localAssumptions = new HashMap<>(); - private final Map localBreakpoints = new HashMap<>(); - - public void setBreakpoint(SourceLineLocation sourceLine, RubyProc proc) { - final CyclicAssumption assumption = lineAssumptions.get(sourceLine); - - if (assumption == null) { - throw new RuntimeException("Breakpoint " + sourceLine + " not found"); - } else { - lineBreakpoints.put(sourceLine, proc); - assumption.invalidate(); - } - } - - public void setBreakpoint(MethodLocal methodLocal, RubyProc proc) { - final CyclicAssumption assumption = localAssumptions.get(methodLocal); - - if (assumption == null) { - throw new RuntimeException("Breakpoint " + methodLocal + " not found"); - } else { - localBreakpoints.put(methodLocal, proc); - assumption.invalidate(); - } - } - - public void removeBreakpoint(SourceLineLocation sourceLine) { - final CyclicAssumption assumption = lineAssumptions.get(sourceLine); - - if (assumption == null) { - throw new RuntimeException("Breakpoint " + sourceLine + " not found"); - } else { - lineBreakpoints.remove(sourceLine); - assumption.invalidate(); - } - } - - public void removeBreakpoint(MethodLocal methodLocal) { - final CyclicAssumption assumption = localAssumptions.get(methodLocal); - - if (assumption == null) { - throw new RuntimeException("Breakpoint " + methodLocal + " not found"); - } else { - localBreakpoints.remove(methodLocal); - assumption.invalidate(); - } - } - - public Assumption getAssumption(SourceLineLocation sourceLine) { - CyclicAssumption assumption = lineAssumptions.get(sourceLine); - - if (assumption == null) { - assumption = new CyclicAssumption(sourceLine.toString()); - lineAssumptions.put(sourceLine, assumption); - } - - return assumption.getAssumption(); - } - - public RubyProc getBreakpoint(SourceLineLocation sourceLine) { - return lineBreakpoints.get(sourceLine); - } - - public Assumption getAssumption(MethodLocal methodLocal) { - CyclicAssumption assumption = localAssumptions.get(methodLocal); - - if (assumption == null) { - assumption = new CyclicAssumption(methodLocal.toString()); - localAssumptions.put(methodLocal, assumption); - } - - return assumption.getAssumption(); - } - - public RubyProc getBreakpoint(MethodLocal methodLocal) { - return localBreakpoints.get(methodLocal); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/lookup/LookupFork.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/lookup/LookupFork.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,97 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.lookup; - -import java.util.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.utilities.*; -import com.oracle.truffle.ruby.runtime.methods.*; - -/** - * A fork in the lookup graph. Look at first and then look at second. - */ -public class LookupFork implements LookupNode { - - private LookupNode first; - private LookupNode second; - - public LookupFork(LookupNode first, LookupNode second) { - this.first = first; - this.second = second; - } - - public boolean setClassVariableIfAlreadySet(String variableName, Object value) { - if (first.setClassVariableIfAlreadySet(variableName, value)) { - return true; - } - - return second.setClassVariableIfAlreadySet(variableName, value); - } - - @Override - public Object lookupConstant(String constantName) { - final Object firstResult = first.lookupConstant(constantName); - - if (firstResult != null) { - return firstResult; - } - - return second.lookupConstant(constantName); - } - - @Override - public Object lookupClassVariable(String classVariable) { - final Object firstResult = first.lookupClassVariable(classVariable); - - if (firstResult != null) { - return firstResult; - } - - return second.lookupClassVariable(classVariable); - } - - @Override - public RubyMethod lookupMethod(String methodName) { - final RubyMethod firstResult = first.lookupMethod(methodName); - - if (firstResult != null) { - return firstResult; - } - - return second.lookupMethod(methodName); - } - - @Override - public Assumption getUnmodifiedAssumption() { - return new UnionAssumption(first.getUnmodifiedAssumption(), second.getUnmodifiedAssumption()); - } - - public LookupNode getFirst() { - return first; - } - - public LookupNode getSecond() { - return second; - } - - public Set getClassVariables() { - final Set classVariables = new HashSet<>(); - classVariables.addAll(first.getClassVariables()); - classVariables.addAll(second.getClassVariables()); - return classVariables; - } - - public void getMethods(Map methods) { - second.getMethods(methods); - first.getMethods(methods); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/lookup/LookupNode.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/lookup/LookupNode.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.lookup; - -import java.util.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.ruby.runtime.methods.*; - -/** - * A node in the lookup graph. We abstract from modules and classes because with includes and - * singletons and so on there are more nodes in the graph than there are classes and modules. - */ -public interface LookupNode { - - boolean setClassVariableIfAlreadySet(String variableName, Object value); - - Object lookupConstant(String constantName); - - Object lookupClassVariable(String variableName); - - RubyMethod lookupMethod(String methodName); - - Assumption getUnmodifiedAssumption(); - - Set getClassVariables(); - - void getMethods(Map methods); - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/lookup/LookupTerminal.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/lookup/LookupTerminal.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.lookup; - -import java.util.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.utilities.*; -import com.oracle.truffle.ruby.runtime.methods.*; - -/** - * A terminal in the lookup graph. - */ -public class LookupTerminal implements LookupNode { - - public static final LookupTerminal INSTANCE = new LookupTerminal(); - - public boolean setClassVariableIfAlreadySet(String variableName, Object value) { - return false; - } - - @Override - public Object lookupConstant(String constantName) { - return null; - } - - @Override - public Object lookupClassVariable(String constantName) { - return null; - } - - @Override - public RubyMethod lookupMethod(String methodName) { - return null; - } - - @Override - public Assumption getUnmodifiedAssumption() { - return AlwaysValidAssumption.INSTANCE; - } - - public Set getClassVariables() { - return Collections.emptySet(); - } - - public void getMethods(Map methods) { - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/methods/Arity.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/methods/Arity.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.methods; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.control.*; - -/** - * Represents the arity, or parameter contract, of a method. - */ -public class Arity { - - private final int minimum; - public static final int NO_MINIMUM = 0; - - private final int maximum; - public static final int NO_MAXIMUM = Integer.MAX_VALUE; - - public static final Arity NO_ARGS = new Arity(0, 0); - public static final Arity ONE_ARG = new Arity(1, 1); - - public Arity(int minimum, int maximum) { - this.minimum = minimum; - this.maximum = maximum; - } - - public void checkArguments(RubyContext context, Object[] arguments) { - if (arguments.length < minimum || arguments.length > maximum) { - CompilerDirectives.transferToInterpreter(); - throw new RaiseException(context.getCoreLibrary().argumentError(arguments.length, minimum)); - } - } - - public int getMinimum() { - return minimum; - } - - public int getMaximum() { - return maximum; - } - - @Override - public String toString() { - return String.format("Arity(%d, %d)", minimum, maximum); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/methods/CallTargetMethodImplementation.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/methods/CallTargetMethodImplementation.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.methods; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; - -public class CallTargetMethodImplementation implements MethodImplementation { - - private final CallTarget callTarget; - private final MaterializedFrame declarationFrame; - - public CallTargetMethodImplementation(CallTarget callTarget, MaterializedFrame declarationFrame) { - assert callTarget != null; - - this.callTarget = callTarget; - this.declarationFrame = declarationFrame; - } - - public Object call(PackedFrame caller, Object self, RubyProc block, Object... args) { - assert RubyContext.shouldObjectBeVisible(self); - assert RubyContext.shouldObjectsBeVisible(args); - - RubyArguments arguments = new RubyArguments(declarationFrame, self, block, args); - - final Object result = callTarget.call(caller, arguments); - - assert RubyContext.shouldObjectBeVisible(result); - - return result; - } - - public MaterializedFrame getDeclarationFrame() { - return declarationFrame; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/methods/MethodImplementation.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/methods/MethodImplementation.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,19 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.methods; - -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.ruby.runtime.core.*; - -public interface MethodImplementation { - - Object call(PackedFrame caller, Object self, RubyProc block, Object... args); - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/methods/RubyMethod.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/methods/RubyMethod.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,168 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.methods; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -/** - * Any kind of Ruby method - so normal methods in classes and modules, but also blocks, procs, - * lambdas and native methods written in Java. - */ -public class RubyMethod { - - private final SourceSection sourceSection; - private final RubyModule declaringModule; - private final UniqueMethodIdentifier uniqueIdentifier; - private final String intrinsicName; - private final String name; - private final Visibility visibility; - private final boolean undefined; - - private final MethodImplementation implementation; - - public RubyMethod(SourceSection sourceSection, RubyModule declaringModule, UniqueMethodIdentifier uniqueIdentifier, String intrinsicName, String name, Visibility visibility, boolean undefined, - MethodImplementation implementation) { - this.sourceSection = sourceSection; - this.declaringModule = declaringModule; - this.uniqueIdentifier = uniqueIdentifier; - this.intrinsicName = intrinsicName; - this.name = name; - this.visibility = visibility; - this.undefined = undefined; - this.implementation = implementation; - } - - public Object call(PackedFrame caller, Object self, RubyProc block, Object... args) { - assert RubyContext.shouldObjectBeVisible(self); - assert RubyContext.shouldObjectsBeVisible(args); - - final Object result = implementation.call(caller, self, block, args); - - assert RubyContext.shouldObjectBeVisible(result); - - return result; - } - - public SourceSection getSourceSection() { - return sourceSection; - } - - public UniqueMethodIdentifier getUniqueIdentifier() { - return uniqueIdentifier; - } - - public String getIntrinsicName() { - return intrinsicName; - } - - public String getName() { - return name; - } - - public Visibility getVisibility() { - return visibility; - } - - public boolean isUndefined() { - return undefined; - } - - public MethodImplementation getImplementation() { - return implementation; - } - - public RubyMethod withNewName(String newName) { - if (newName.equals(name)) { - return this; - } - - return new RubyMethod(sourceSection, declaringModule, uniqueIdentifier, intrinsicName, newName, visibility, undefined, implementation); - } - - public RubyMethod withNewVisibility(Visibility newVisibility) { - if (newVisibility == visibility) { - return this; - } - - return new RubyMethod(sourceSection, declaringModule, uniqueIdentifier, intrinsicName, name, newVisibility, undefined, implementation); - } - - public RubyMethod withDeclaringModule(RubyModule newDeclaringModule) { - if (newDeclaringModule == declaringModule) { - return this; - } - - return new RubyMethod(sourceSection, newDeclaringModule, uniqueIdentifier, intrinsicName, name, visibility, undefined, implementation); - } - - public RubyMethod undefined() { - if (undefined) { - return this; - } - - return new RubyMethod(sourceSection, declaringModule, uniqueIdentifier, intrinsicName, name, visibility, true, implementation); - } - - public boolean isVisibleTo(RubyBasicObject caller) { - if (caller instanceof RubyModule) { - if (isVisibleTo((RubyModule) caller)) { - return true; - } - } - - if (isVisibleTo(caller.getRubyClass())) { - return true; - } - - if (isVisibleTo(caller.getSingletonClass())) { - return true; - } - - return false; - } - - private boolean isVisibleTo(RubyModule module) { - switch (visibility) { - case PUBLIC: - return true; - - case PROTECTED: - return true; - - case PRIVATE: - if (module == declaringModule) { - return true; - } - - if (module.getSingletonClass() == declaringModule) { - return true; - } - - if (module.getParentModule() != null && isVisibleTo(module.getParentModule())) { - return true; - } - - return false; - - default: - return false; - } - } - - @Override - public String toString() { - return implementation.toString(); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/methods/UniqueMethodIdentifier.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/methods/UniqueMethodIdentifier.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,18 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.methods; - -/** - * An object that uniquely identifies a method as it appears in the source code, and that follows - * the method as a normal method, when it becomes a proc, when it changes access or is aliased etc. - */ -public class UniqueMethodIdentifier { - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/methods/Visibility.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/methods/Visibility.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,17 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.methods; - -/** - * Represents the visibility of a method. - */ -public enum Visibility { - PUBLIC, PROTECTED, PRIVATE -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/objects/FixnumStorageLocation.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/objects/FixnumStorageLocation.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.objects; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.runtime.*; - -/** - * A storage location for Fixnums. - */ -public class FixnumStorageLocation extends PrimitiveStorageLocation { - - public FixnumStorageLocation(ObjectLayout objectLayout, long offset, int mask) { - super(objectLayout, offset, mask); - } - - @Override - public Object read(RubyBasicObject object, boolean condition) { - try { - return readFixnum(object, condition); - } catch (UnexpectedResultException e) { - return e.getResult(); - } - } - - public int readFixnum(RubyBasicObject object, boolean condition) throws UnexpectedResultException { - if (isSet(object)) { - return CompilerDirectives.unsafeGetInt(object, offset, condition, this); - } else { - throw new UnexpectedResultException(NilPlaceholder.INSTANCE); - } - } - - @Override - public void write(RubyBasicObject object, Object value) throws GeneralizeStorageLocationException { - if (value instanceof Integer) { - writeFixnum(object, (int) value); - } else if (value instanceof NilPlaceholder) { - markAsUnset(object); - } else { - throw new GeneralizeStorageLocationException(); - } - } - - public void writeFixnum(RubyBasicObject object, int value) { - CompilerDirectives.unsafePutInt(object, offset, value, null); - markAsSet(object); - } - - @Override - public Class getStoredClass() { - return Integer.class; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/objects/FloatStorageLocation.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/objects/FloatStorageLocation.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.objects; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.ruby.runtime.*; - -/** - * A storage location for Floats. - */ -public class FloatStorageLocation extends PrimitiveStorageLocation { - - public FloatStorageLocation(ObjectLayout objectLayout, long offset, int mask) { - super(objectLayout, offset, mask); - } - - @Override - public Object read(RubyBasicObject object, boolean condition) { - try { - return readFloat(object, condition); - } catch (UnexpectedResultException e) { - return e.getResult(); - } - } - - public double readFloat(RubyBasicObject object, boolean condition) throws UnexpectedResultException { - if (isSet(object)) { - return CompilerDirectives.unsafeGetDouble(object, offset, condition, this); - } else { - throw new UnexpectedResultException(NilPlaceholder.INSTANCE); - } - } - - @Override - public void write(RubyBasicObject object, Object value) throws GeneralizeStorageLocationException { - if (value instanceof Double) { - writeFloat(object, (double) value); - } else if (value instanceof NilPlaceholder) { - markAsUnset(object); - } else { - throw new GeneralizeStorageLocationException(); - } - } - - public void writeFloat(RubyBasicObject object, Double value) { - CompilerDirectives.unsafePutDouble(object, offset, value, null); - markAsSet(object); - } - - @Override - public Class getStoredClass() { - return Double.class; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/objects/GeneralizeStorageLocationException.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/objects/GeneralizeStorageLocationException.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,19 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.objects; - -/** - * Indicates that a storage location cannot store the type of value that you asked it to. - */ -public class GeneralizeStorageLocationException extends Exception { - - private static final long serialVersionUID = -5136358171098229961L; - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/objects/ObjectLayout.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/objects/ObjectLayout.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,235 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.objects; - -import java.lang.reflect.*; -import java.util.*; -import java.util.Map.Entry; - -import sun.misc.*; - -import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.nodes.NodeUtil.*; - -/** - * Maps names of instance variables to storage locations, which are either the offset of a primitive - * field in {@code RubyBasicObject}, or an index into an object array in {@code RubyBasicObject}. - * Object layouts are chained, with each having zero or one parents. - *

- * Object layouts are immutable, with the methods for adding new instance variables of generalizing - * the type of existing instance variables returning new object layouts. - */ -public class ObjectLayout { - - public static final ObjectLayout EMPTY = new ObjectLayout("(empty)"); - - private final String originHint; - - private final ObjectLayout parent; - - private final Map storageLocations = new HashMap<>(); - - private final int primitiveStorageLocationsUsed; - private final int objectStorageLocationsUsed; - - public static final long FIRST_OFFSET = getFirstOffset(); - - private ObjectLayout(String originHint) { - this.originHint = originHint; - this.parent = null; - primitiveStorageLocationsUsed = 0; - objectStorageLocationsUsed = 0; - } - - public ObjectLayout(String originHint, ObjectLayout parent) { - this(originHint, parent, new HashMap()); - } - - public ObjectLayout(String originHint, ObjectLayout parent, Map storageTypes) { - this.originHint = originHint; - this.parent = parent; - - // Start our offsets from where the parent ends - - int primitiveStorageLocationIndex; - int objectStorageLocationIndex; - - if (parent == null) { - primitiveStorageLocationIndex = 0; - objectStorageLocationIndex = 0; - } else { - primitiveStorageLocationIndex = parent.primitiveStorageLocationsUsed; - objectStorageLocationIndex = parent.objectStorageLocationsUsed; - } - - // Go through the variables we've been asked to store - - for (Entry entry : storageTypes.entrySet()) { - // TODO(cs): what if parent has it, but we need a more general type? - - final String name = entry.getKey(); - final Class type = entry.getValue(); - - if (parent == null || parent.findStorageLocation(name) == null) { - boolean canStoreInPrimitive = false; - int primitivesNeeded = 0; - - if (type == Integer.class) { - canStoreInPrimitive = true; - primitivesNeeded = 1; - } else if (type == Double.class) { - canStoreInPrimitive = true; - primitivesNeeded = 2; - } - - if (canStoreInPrimitive && primitiveStorageLocationIndex + primitivesNeeded <= RubyBasicObject.PRIMITIVE_STORAGE_LOCATIONS_COUNT) { - final long offset = FIRST_OFFSET + Unsafe.ARRAY_INT_INDEX_SCALE * primitiveStorageLocationIndex; - final int mask = 1 << primitiveStorageLocationIndex; - - StorageLocation newStorageLocation = null; - - if (type == Integer.class) { - newStorageLocation = new FixnumStorageLocation(this, offset, mask); - } else if (type == Double.class) { - newStorageLocation = new FloatStorageLocation(this, offset, mask); - } - - storageLocations.put(entry.getKey(), newStorageLocation); - primitiveStorageLocationIndex += primitivesNeeded; - } else { - final ObjectStorageLocation newStorageLocation = new ObjectStorageLocation(this, objectStorageLocationIndex); - storageLocations.put(entry.getKey(), newStorageLocation); - objectStorageLocationIndex++; - } - } - } - - primitiveStorageLocationsUsed = primitiveStorageLocationIndex; - objectStorageLocationsUsed = objectStorageLocationIndex; - } - - /** - * Create a new version of this layout, but with a different parent. The new parent probably - * comes from the same Ruby class as it did, but it's a new layout because layouts are - * immutable, so modifications to the superclass yields a new layout. - */ - public ObjectLayout renew(ObjectLayout newParent) { - return new ObjectLayout(originHint + ".renewed", newParent, getStorageTypes()); - } - - /** - * Create a new version of this layout but with a new variable. - */ - public ObjectLayout withNewVariable(String name, Class type) { - final Map storageTypes = getStorageTypes(); - storageTypes.put(name, type); - return new ObjectLayout(originHint + ".withnew", parent, storageTypes); - } - - /** - * Create a new version of this layout but with an existing variable generalized to support any - * type. - */ - public ObjectLayout withGeneralisedVariable(String name) { - return withNewVariable(name, Object.class); - } - - /** - * Get a map of instance variable names to the type that they store. - */ - public Map getStorageTypes() { - Map storageTypes = new HashMap<>(); - - for (Entry entry : storageLocations.entrySet()) { - final String name = entry.getKey(); - final StorageLocation storageLocation = entry.getValue(); - - if (storageLocation.getStoredClass() != null) { - storageTypes.put(name, storageLocation.getStoredClass()); - } - } - - return storageTypes; - } - - /** - * Get a map of instance variable names to the type that they store, but including both this - * layout and all parent layouts. - */ - public Map getAllStorageLocations() { - final Map allStorageLocations = new HashMap<>(); - - allStorageLocations.putAll(storageLocations); - - if (parent != null) { - allStorageLocations.putAll(parent.getAllStorageLocations()); - } - - return allStorageLocations; - } - - /** - * Find a storage location from a name, including in parents. - */ - public StorageLocation findStorageLocation(String name) { - final StorageLocation storageLocation = storageLocations.get(name); - - if (storageLocation != null) { - return storageLocation; - } - - if (parent == null) { - return null; - } - - return parent.findStorageLocation(name); - } - - public int getObjectStorageLocationsUsed() { - return objectStorageLocationsUsed; - } - - /** - * Does this layout include another layout? That is, is that other layout somewhere in the chain - * of parents? We say 'include' because all of the variables in a parent layout are available in - * your layout as well. - */ - public boolean contains(ObjectLayout other) { - ObjectLayout layout = this; - - do { - if (other == layout) { - return true; - } - - layout = layout.parent; - } while (layout != null); - - return false; - } - - public String getOriginHint() { - return originHint; - } - - private static long getFirstOffset() { - try { - final Field fieldOffsetProviderField = NodeUtil.class.getDeclaredField("unsafeFieldOffsetProvider"); - fieldOffsetProviderField.setAccessible(true); - final FieldOffsetProvider fieldOffsetProvider = (FieldOffsetProvider) fieldOffsetProviderField.get(null); - - final Field firstPrimitiveField = RubyBasicObject.class.getDeclaredField("primitiveStorageLocation01"); - return fieldOffsetProvider.objectFieldOffset(firstPrimitiveField); - } catch (NoSuchFieldException | IllegalAccessException e) { - throw new RuntimeException(e); - } - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/objects/ObjectStorageLocation.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/objects/ObjectStorageLocation.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.objects; - -import com.oracle.truffle.ruby.runtime.*; - -/** - * A storage location for any object. - */ -public class ObjectStorageLocation extends StorageLocation { - - private final int index; - - public ObjectStorageLocation(ObjectLayout objectLayout, int index) { - super(objectLayout); - this.index = index; - } - - @Override - public boolean isSet(RubyBasicObject object) { - return object.objectStorageLocations[index] != null; - } - - @Override - public Object read(RubyBasicObject object, boolean condition) { - final Object result = object.objectStorageLocations[index]; - - if (result == null) { - return NilPlaceholder.INSTANCE; - } else { - return result; - } - } - - @Override - public void write(RubyBasicObject object, Object value) { - object.objectStorageLocations[index] = value; - } - - @Override - public Class getStoredClass() { - return Object.class; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/objects/PrimitiveStorageLocation.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/objects/PrimitiveStorageLocation.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.objects; - -/** - * A storage location that uses one of the primitive fields in {@code RubyBasObject}. - */ -public abstract class PrimitiveStorageLocation extends StorageLocation { - - protected final long offset; - protected final int mask; - - protected PrimitiveStorageLocation(ObjectLayout objectLayout, long offset, int mask) { - super(objectLayout); - this.offset = offset; - this.mask = mask; - } - - @Override - public boolean isSet(RubyBasicObject object) { - return (object.primitiveSetMap & mask) != 0; - } - - protected void markAsSet(RubyBasicObject object) { - object.primitiveSetMap |= mask; - } - - protected void markAsUnset(RubyBasicObject object) { - object.primitiveSetMap &= ~mask; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/objects/RubyBasicObject.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/objects/RubyBasicObject.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,360 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.objects; - -import java.util.*; -import java.util.Map.Entry; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.control.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.lookup.*; -import com.oracle.truffle.ruby.runtime.methods.*; - -/** - * Represents the Ruby {@code BasicObject} class - the root of the Ruby class hierarchy. - */ -public class RubyBasicObject { - - @CompilationFinal protected RubyClass rubyClass; - protected RubyClass rubySingletonClass; - - protected LookupNode lookupNode; - - protected long objectID = -1; - - public boolean hasPrivateLayout = false; - private ObjectLayout objectLayout; - - public static final int PRIMITIVE_STORAGE_LOCATIONS_COUNT = 14; - protected int primitiveStorageLocation01; - protected int primitiveStorageLocation02; - protected int primitiveStorageLocation03; - protected int primitiveStorageLocation04; - protected int primitiveStorageLocation05; - protected int primitiveStorageLocation06; - protected int primitiveStorageLocation07; - protected int primitiveStorageLocation08; - protected int primitiveStorageLocation09; - protected int primitiveStorageLocation10; - protected int primitiveStorageLocation11; - protected int primitiveStorageLocation12; - protected int primitiveStorageLocation13; - protected int primitiveStorageLocation14; - - // A bit map to indicate which primitives are set, so that they can be Nil - protected int primitiveSetMap; - - protected Object[] objectStorageLocations; - - public RubyBasicObject(RubyClass rubyClass) { - if (rubyClass != null) { - unsafeSetRubyClass(rubyClass); - - if (rubyClass.getContext().getConfiguration().getFullObjectSpace()) { - rubyClass.getContext().getObjectSpaceManager().add(this); - } - } - } - - public void initialize() { - } - - public LookupNode getLookupNode() { - return lookupNode; - } - - public RubyClass getRubyClass() { - assert rubyClass != null; - return rubyClass; - } - - public boolean hasPrivateLayout() { - return hasPrivateLayout; - } - - public ObjectLayout getObjectLayout() { - return objectLayout; - } - - public ObjectLayout getUpdatedObjectLayout() { - updateLayout(); - return objectLayout; - } - - /** - * Does this object have an instance variable defined? - */ - public boolean isInstanceVariableDefined(String name) { - if (!hasPrivateLayout && objectLayout != rubyClass.getObjectLayoutForInstances()) { - updateLayout(); - } - - return objectLayout.findStorageLocation(name) != null; - } - - /** - * Set an instance variable to be a value. Slow path. - */ - public void setInstanceVariable(String name, Object value) { - CompilerAsserts.neverPartOfCompilation(); - - // If the object's layout doesn't match the class, update - - if (!hasPrivateLayout && objectLayout != rubyClass.getObjectLayoutForInstances()) { - updateLayout(); - } - - // Find the storage location - - StorageLocation storageLocation = objectLayout.findStorageLocation(name); - - if (storageLocation == null) { - /* - * It doesn't exist, so create a new layout for the class that includes it and update - * the layout of this object. - */ - - rubyClass.setObjectLayoutForInstances(rubyClass.getObjectLayoutForInstances().withNewVariable(name, value.getClass())); - updateLayout(); - - storageLocation = objectLayout.findStorageLocation(name); - } - - // Try to write to that storage location - - try { - storageLocation.write(this, value); - } catch (GeneralizeStorageLocationException e) { - /* - * It might not be able to store the type that we passed, if not generalize the class's - * layout and update the layout of this object. - */ - - rubyClass.setObjectLayoutForInstances(rubyClass.getObjectLayoutForInstances().withGeneralisedVariable(name)); - updateLayout(); - - storageLocation = objectLayout.findStorageLocation(name); - - // Try to write to the generalized storage location - - try { - storageLocation.write(this, value); - } catch (GeneralizeStorageLocationException e1) { - // We know that we just generalized it, so this should not happen - throw new RuntimeException("Generalised an instance variable, but it still rejected the value"); - } - } - } - - /** - * Get the value of an instance variable, or Nil if it isn't defined. Slow path. - */ - public Object getInstanceVariable(String name) { - CompilerAsserts.neverPartOfCompilation(); - - // If the object's layout doesn't match the class, update - - if (!hasPrivateLayout && objectLayout != rubyClass.getObjectLayoutForInstances()) { - updateLayout(); - } - - // Find the storage location - - final StorageLocation storageLocation = objectLayout.findStorageLocation(name); - - // Get the value - - if (storageLocation == null) { - return NilPlaceholder.INSTANCE; - } - - return storageLocation.read(this, true); - } - - public String[] getInstanceVariableNames() { - final Set instanceVariableNames = getInstanceVariables().keySet(); - return instanceVariableNames.toArray(new String[instanceVariableNames.size()]); - } - - public RubyClass getSingletonClass() { - if (rubySingletonClass == null) { - /* - * The object a of class A has a singleton class a' of class Class, with name - * #>, and with superclass that is A. - * - * irb(main):001:0> class A; end - * - * => nil - * - * irb(main):002:0> a = A.new - * - * => # - * - * irb(main):003:0> a.singleton_class - * - * => #> - * - * irb(main):004:0> a.singleton_class.class - * - * => Class - * - * irb(main):005:0> a.singleton_class.superclass - * - * => A - */ - - rubySingletonClass = new RubyClass(rubyClass.getParentModule(), rubyClass, String.format("#>", rubyClass.getName(), getObjectID()), true); - - lookupNode = new LookupFork(rubySingletonClass, rubyClass); - } - - return rubySingletonClass; - } - - public long getObjectID() { - if (objectID == -1) { - objectID = rubyClass.getContext().getNextObjectID(); - } - - return objectID; - } - - public String inspect() { - return toString(); - } - - /** - * Get a map of all instance variables. - */ - protected Map getInstanceVariables() { - if (objectLayout == null) { - return Collections.emptyMap(); - } - - final Map instanceVariableMap = new HashMap<>(); - - for (Entry entry : objectLayout.getAllStorageLocations().entrySet()) { - final String name = entry.getKey(); - final StorageLocation storageLocation = entry.getValue(); - - if (storageLocation.isSet(this)) { - instanceVariableMap.put(name, storageLocation.read(this, true)); - } - } - - return instanceVariableMap; - } - - /** - * Set instance variables from a map. - */ - protected void setInstanceVariables(Map instanceVariables) { - assert instanceVariables != null; - - if (objectLayout == null) { - updateLayout(); - } - - for (Entry entry : instanceVariables.entrySet()) { - final StorageLocation storageLocation = objectLayout.findStorageLocation(entry.getKey()); - assert storageLocation != null; - - try { - storageLocation.write(this, entry.getValue()); - } catch (GeneralizeStorageLocationException e) { - throw new RuntimeException("Should not have to be generalising when setting instance variables - " + entry.getValue().getClass().getName() + ", " + - storageLocation.getStoredClass().getName()); - } - } - } - - /** - * Update the layout of this object to match that of its class. - */ - @CompilerDirectives.SlowPath - public void updateLayout() { - // Get the current values of instance variables - - final Map instanceVariableMap = getInstanceVariables(); - - // Use the layout of the class - - objectLayout = rubyClass.getObjectLayoutForInstances(); - - // Make all primitives as unset - - primitiveSetMap = 0; - - // Create a new array for objects - - allocateObjectStorageLocations(); - - // Restore values - - setInstanceVariables(instanceVariableMap); - } - - private void allocateObjectStorageLocations() { - final int objectStorageLocationsUsed = objectLayout.getObjectStorageLocationsUsed(); - - if (objectStorageLocationsUsed == 0) { - objectStorageLocations = null; - } else { - objectStorageLocations = new Object[objectStorageLocationsUsed]; - } - } - - public void switchToPrivateLayout() { - final Map instanceVariables = getInstanceVariables(); - - hasPrivateLayout = true; - objectLayout = ObjectLayout.EMPTY; - - for (Entry entry : instanceVariables.entrySet()) { - objectLayout = objectLayout.withNewVariable(entry.getKey(), entry.getValue().getClass()); - } - - setInstanceVariables(instanceVariables); - } - - public void extend(RubyModule module) { - getSingletonClass().include(module); - } - - @Override - public String toString() { - return "#<" + rubyClass.getName() + ":0x" + Long.toHexString(getObjectID()) + ">"; - } - - public boolean hasSingletonClass() { - return rubySingletonClass != null; - } - - public Object send(String name, RubyProc block, Object... args) { - final RubyMethod method = getLookupNode().lookupMethod(name); - - if (method == null || method.isUndefined()) { - throw new RaiseException(getRubyClass().getContext().getCoreLibrary().noMethodError(name, toString())); - } - - return method.call(null, this, block, args); - } - - public void unsafeSetRubyClass(RubyClass newRubyClass) { - assert rubyClass == null; - - rubyClass = newRubyClass; - lookupNode = rubyClass; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/objects/StorageLocation.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/objects/StorageLocation.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.objects; - -/** - * A storage location that abstracts the method for reading and writing values. - */ -public abstract class StorageLocation { - - private ObjectLayout objectLayout; - - protected StorageLocation(ObjectLayout objectLayout) { - this.objectLayout = objectLayout; - } - - public abstract boolean isSet(RubyBasicObject object); - - public abstract Object read(RubyBasicObject object, boolean condition); - - public abstract void write(RubyBasicObject object, Object value) throws GeneralizeStorageLocationException; - - public abstract Class getStoredClass(); - - public ObjectLayout getObjectLayout() { - return objectLayout; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/objects/Unboxable.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/objects/Unboxable.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,19 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.objects; - -/** - * An object that can be losslessly unboxed back to a more primitive value. - */ -public interface Unboxable { - - Object unbox(); - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/subsystems/AtExitManager.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/subsystems/AtExitManager.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.subsystems; - -import java.util.*; - -import com.oracle.truffle.ruby.runtime.core.*; - -/** - * Manages at_exit callbacks. - */ -public class AtExitManager { - - private final List blocks = new ArrayList<>(); - - public void add(RubyProc block) { - blocks.add(block); - } - - public void run() { - final ListIterator iterator = blocks.listIterator(blocks.size()); - - while (iterator.hasPrevious()) { - iterator.previous().call(null); - } - } -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/subsystems/FeatureManager.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/subsystems/FeatureManager.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,141 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.subsystems; - -import java.io.*; -import java.net.*; -import java.util.*; - -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.control.*; -import com.oracle.truffle.ruby.runtime.core.array.*; - -/** - * Manages the features loaded into Ruby. This basically means which library files are loaded, but - * Ruby often talks about requiring features, not files. - * - */ -public class FeatureManager { - - private RubyContext context; - - private final Set requiredFiles = new HashSet<>(); - - public FeatureManager(RubyContext context) { - this.context = context; - } - - public boolean require(String feature) throws IOException { - // Some features are handled specially - - if (feature.equals("stringio")) { - context.implementationMessage("stringio not yet implemented"); - return true; - } - - if (feature.equals("rbconfig")) { - // Kernel#rbconfig is always there - return true; - } - - if (feature.equals("pp")) { - // Kernel#pretty_inspect is always there - return true; - } - - // Get the load path - - final Object loadPathObject = context.getCoreLibrary().getGlobalVariablesObject().getInstanceVariable("$:"); - - if (!(loadPathObject instanceof RubyArray)) { - throw new RuntimeException("$: is not an array"); - } - - final List loadPath = ((RubyArray) loadPathObject).asList(); - - // Try as a full path - - if (requireInPath("", feature)) { - return true; - } - - // Try each load path in turn - - for (Object pathObject : loadPath) { - final String path = pathObject.toString(); - - if (requireInPath(path, feature)) { - return true; - } - } - - // Didn't find the feature - - throw new RaiseException(context.getCoreLibrary().loadErrorCannotLoad(feature)); - } - - public boolean requireInPath(String path, String feature) throws IOException { - if (requireFile(feature)) { - return true; - } - - if (requireFile(feature + ".rb")) { - return true; - } - - if (requireFile(path + File.separator + feature)) { - return true; - } - - if (requireFile(path + File.separator + feature + ".rb")) { - return true; - } - - return false; - } - - private boolean requireFile(String fileName) throws IOException { - if (requiredFiles.contains(fileName)) { - return true; - } - - /* - * There is unfortunately no way to check if a string is a file path, or a URL. file:foo.txt - * is a valid file name, as well as a valid URL. We try as a file path first. - */ - - if (new File(fileName).isFile()) { - context.loadFile(fileName); - requiredFiles.add(fileName); - return true; - } else { - URL url; - - try { - url = new URL(fileName); - } catch (MalformedURLException e) { - return false; - } - - InputStream inputStream; - - try { - inputStream = url.openConnection().getInputStream(); - } catch (IOException e) { - return false; - } - - context.load(context.getSourceManager().get(url.toString(), inputStream)); - requiredFiles.add(fileName); - return true; - } - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/subsystems/FiberManager.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/subsystems/FiberManager.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.subsystems; - -import java.util.*; -import java.util.concurrent.*; - -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; - -/** - * Manages Ruby {@code Fiber} objects. - */ -public class FiberManager { - - private final RubyFiber rootFiber; - private RubyFiber currentFiber; - - private final Set runningFibers = Collections.newSetFromMap(new ConcurrentHashMap()); - - public FiberManager(RubyContext context) { - rootFiber = new RubyFiber(context.getCoreLibrary().getFiberClass(), this, context.getThreadManager()); - currentFiber = rootFiber; - } - - public RubyFiber getCurrentFiber() { - return currentFiber; - } - - public void setCurrentFiber(RubyFiber fiber) { - currentFiber = fiber; - } - - public void registerFiber(RubyFiber fiber) { - runningFibers.add(fiber); - } - - public void unregisterFiber(RubyFiber fiber) { - runningFibers.remove(fiber); - } - - public void shutdown() { - for (RubyFiber fiber : runningFibers) { - fiber.shutdown(); - } - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/subsystems/ObjectSpaceManager.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/subsystems/ObjectSpaceManager.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,193 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.subsystems; - -import java.lang.ref.*; -import java.util.*; -import java.util.concurrent.*; - -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -/** - * Supports the Ruby {@code ObjectSpace} module. Object IDs are lazily allocated {@code long} - * values, mapped to objects with a weak hash map. Finalizers are implemented with weak references - * and reference queues, and are run in a dedicated Ruby thread (but not a dedicated Java thread). - */ -public class ObjectSpaceManager { - - private class FinalizerReference extends WeakReference { - - public List finalizers = new LinkedList<>(); - - public FinalizerReference(RubyBasicObject object, ReferenceQueue queue) { - super(object, queue); - } - - public void addFinalizer(RubyProc proc) { - finalizers.add(proc); - } - - public List getFinalizers() { - return finalizers; - } - - public void clearFinalizers() { - finalizers = new LinkedList<>(); - } - - } - - private final RubyContext context; - - // TODO(cs): this is wrong - WeakHashMap is not weak in the value - private final WeakHashMap objects = new WeakHashMap<>(); - - private final Map finalizerReferences = new WeakHashMap<>(); - private final ReferenceQueue finalizerQueue = new ReferenceQueue<>(); - private RubyThread finalizerThread; - private Thread finalizerJavaThread; - private boolean stop; - private CountDownLatch finished = new CountDownLatch(1); - - public ObjectSpaceManager(RubyContext context) { - this.context = context; - } - - public void add(RubyBasicObject object) { - objects.put(object.getObjectID(), object); - } - - public RubyBasicObject lookupId(long id) { - return objects.get(id); - } - - public void defineFinalizer(RubyBasicObject object, RubyProc proc) { - // Record the finalizer against the object - - FinalizerReference finalizerReference = finalizerReferences.get(object); - - if (finalizerReference == null) { - finalizerReference = new FinalizerReference(object, finalizerQueue); - finalizerReferences.put(object, finalizerReference); - } - - finalizerReference.addFinalizer(proc); - - // If there is no finalizer thread, start one - - if (finalizerThread == null) { - finalizerThread = new RubyThread(context.getCoreLibrary().getThreadClass(), context.getThreadManager()); - - finalizerThread.initialize(new Runnable() { - - @Override - public void run() { - runFinalizers(); - } - - }); - } - } - - public void undefineFinalizer(RubyBasicObject object) { - final FinalizerReference finalizerReference = finalizerReferences.get(object); - - if (finalizerReference != null) { - finalizerReference.clearFinalizers(); - } - } - - private void runFinalizers() { - // Run in a loop - - while (true) { - // Is there a finalizer ready to immediately run? - - FinalizerReference finalizerReference = (FinalizerReference) finalizerQueue.poll(); - - if (finalizerReference != null) { - runFinalizers(finalizerReference); - continue; - } - - // Check if we've been asked to stop - - if (stop) { - break; - } - - // Leave the global lock and wait on the finalizer queue - - final RubyThread runningThread = context.getThreadManager().leaveGlobalLock(); - finalizerJavaThread = Thread.currentThread(); - - try { - finalizerReference = (FinalizerReference) finalizerQueue.remove(); - } catch (InterruptedException e) { - continue; - } finally { - context.getThreadManager().enterGlobalLock(runningThread); - } - - runFinalizers(finalizerReference); - } - - finished.countDown(); - } - - private static void runFinalizers(FinalizerReference finalizerReference) { - try { - for (RubyProc proc : finalizerReference.getFinalizers()) { - proc.call(null); - } - } catch (Exception e) { - // MRI seems to silently ignore exceptions in finalizers - } - } - - public void shutdown() { - context.getThreadManager().enterGlobalLock(finalizerThread); - - try { - // Tell the finalizer thread to stop and wait for it to do so - - if (finalizerThread != null) { - stop = true; - - if (finalizerJavaThread != null) { - finalizerJavaThread.interrupt(); - } - - context.getThreadManager().leaveGlobalLock(); - - try { - finished.await(); - } catch (InterruptedException e) { - } finally { - context.getThreadManager().enterGlobalLock(finalizerThread); - } - } - - // Run any finalizers for objects that are still live - - for (FinalizerReference finalizerReference : finalizerReferences.values()) { - runFinalizers(finalizerReference); - } - } finally { - context.getThreadManager().leaveGlobalLock(); - } - } - - public Collection getObjects() { - return objects.values(); - } -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/subsystems/ThreadManager.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/subsystems/ThreadManager.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.subsystems; - -import java.util.*; -import java.util.concurrent.*; -import java.util.concurrent.locks.*; - -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; - -/** - * Manages Ruby {@code Thread} objects. - */ -public class ThreadManager { - - private final ReentrantLock globalLock = new ReentrantLock(); - - private final RubyThread rootThread; - private RubyThread currentThread; - - private final Set runningThreads = Collections.newSetFromMap(new ConcurrentHashMap()); - - public ThreadManager(RubyContext context) { - rootThread = new RubyThread(context.getCoreLibrary().getFiberClass(), this); - runningThreads.add(rootThread); - enterGlobalLock(rootThread); - } - - /** - * Enters the global lock. Reentrant, but be aware that Ruby threads are not one-to-one with - * Java threads. Needs to be told which Ruby thread is becoming active as it can't work this out - * from the current Java thread. Remember to call {@link #leaveGlobalLock} again before - * blocking. - */ - public void enterGlobalLock(RubyThread thread) { - globalLock.lock(); - currentThread = thread; - } - - /** - * Leaves the global lock, returning the Ruby thread which has just stopped being the current - * thread. Remember to call {@link #enterGlobalLock} again with that returned thread before - * executing any Ruby code. You probably want to use this with a {@code finally} statement to - * make sure that happens - */ - public RubyThread leaveGlobalLock() { - if (!globalLock.isHeldByCurrentThread()) { - throw new RuntimeException("You don't own this lock!"); - } - - final RubyThread result = currentThread; - globalLock.unlock(); - return result; - } - - public RubyThread getCurrentThread() { - return currentThread; - } - - public void registerThread(RubyThread thread) { - runningThreads.add(thread); - } - - public void unregisterThread(RubyThread thread) { - runningThreads.remove(thread); - } - - public void shutdown() { - for (RubyThread thread : runningThreads) { - thread.shutdown(); - } - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/subsystems/TraceManager.java --- a/graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/subsystems/TraceManager.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,110 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.runtime.subsystems; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.utilities.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; - -/** - * Manages trace events and calls the user's trace method if one is set. - *

- * Once tracing has been enabled via {@link #setTraceProc(RubyProc)}, the underlying instrumentation - * remains in effect, along with performance impact. - */ -public final class TraceManager { - - private RubyContext context; - - private final AssumedValue traceProc = new AssumedValue<>("trace-proc", null); - private boolean suspended; - - private String lastFile; - private int lastLine; - - private final Assumption notTracingAssumption = Truffle.getRuntime().createAssumption("tracing-disabled"); - - public TraceManager(RubyContext context) { - this.context = context; - } - - /** - * Produce a trace; it is a runtime error if {@link #hasTraceProc()}{@code == false}. - */ - @CompilerDirectives.SlowPath - public void trace(String event, String file, int line, long objectId, RubyBinding binding, String className) { - // If tracing is suspended, stop here - - if (suspended) { - return; - } - - // If the file and line haven't changed since the last trace, stop here - - if (file.equals(lastFile) && line == lastLine) { - return; - } - - final RubyClass stringClass = context.getCoreLibrary().getStringClass(); - - // Suspend tracing while we run the trace proc - - suspended = true; - - try { - // Exceptions from within the proc propagate normally - - traceProc.get().call(null, new RubyString(stringClass, event), // - new RubyString(stringClass, file), // - line, // - GeneralConversions.fixnumOrBignum(objectId), // - GeneralConversions.instanceOrNil(binding), // - GeneralConversions.instanceOrNil(className)); - } finally { - // Resume tracing - - suspended = false; - } - - // Remember the last trace event file and line - - lastFile = file; - lastLine = line; - } - - /** - * Is there a "trace proc" in effect? - */ - public boolean hasTraceProc() { - return traceProc.get() != null; - } - - /** - * Gets the assumption that there has never yet been tracing enabled. Once the assumption is - * invalidated, tracing is presumed permanently enabled even if {@link #hasTraceProc()} returns - * {@code false}. - */ - public Assumption getNotTracingAssumption() { - return notTracingAssumption; - } - - public void setTraceProc(RubyProc newTraceProc) { - if (!context.getConfiguration().getTrace()) { - throw new RuntimeException("You need the --trace option to use tracing"); - } - - traceProc.set(newTraceProc); - lastFile = null; - lastLine = -1; - - notTracingAssumption.invalidate(); - } -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.shell/src/com/oracle/truffle/ruby/shell/CommandLineOptions.java --- a/graal/com.oracle.truffle.ruby.shell/src/com/oracle/truffle/ruby/shell/CommandLineOptions.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,151 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.shell; - -import java.util.*; - -import com.oracle.truffle.ruby.runtime.configuration.*; - -/** - * Options resulting from parsing a command line by {@link CommandLineParser}. - */ -public class CommandLineOptions { - - private final List preRequires; - private final String preChangeDirectory; - - private final List extraLoadPath; - - private final String programFile; - private final List commandLineScripts; - private final List programArgs; - private final List switchArgs; - - private final int recordSeparator; - private final boolean autosplit; - private final String autosplitPattern; - private final boolean checkSyntaxOnly; - private final boolean lineEndingProcessing; - private final boolean inPlaceEdit; - private final String inPlaceBackupExtension; - private final boolean implicitLoop; - private final boolean implicitSedLoop; - private final boolean importFromPath; - private final boolean stripMessage; - private final boolean useJLine; - - private final Configuration configuration; - - public CommandLineOptions(List preRequires, String preChangeDirectory, List extraLoadPath, String programFile, List commandLineScripts, List programArgs, - List switchArgs, int recordSeparator, boolean autosplit, String autosplitPattern, boolean checkSyntaxOnly, boolean lineEndingProcessing, boolean inPlaceEdit, - String inPlaceBackupExtension, boolean implicitLoop, boolean implicitSedLoop, boolean importFromPath, boolean stripMessage, boolean useJLine, Configuration configuration) { - this.preRequires = preRequires; - this.preChangeDirectory = preChangeDirectory; - this.extraLoadPath = extraLoadPath; - this.programFile = programFile; - this.commandLineScripts = commandLineScripts; - this.programArgs = programArgs; - this.switchArgs = switchArgs; - this.recordSeparator = recordSeparator; - this.autosplit = autosplit; - this.autosplitPattern = autosplitPattern; - this.checkSyntaxOnly = checkSyntaxOnly; - this.lineEndingProcessing = lineEndingProcessing; - this.inPlaceEdit = inPlaceEdit; - this.inPlaceBackupExtension = inPlaceBackupExtension; - this.implicitLoop = implicitLoop; - this.implicitSedLoop = implicitSedLoop; - this.importFromPath = importFromPath; - this.stripMessage = stripMessage; - this.useJLine = useJLine; - this.configuration = configuration; - } - - public List getPreRequires() { - return preRequires; - } - - public String getPreChangeDirectory() { - return preChangeDirectory; - } - - public List getExtraLoadPath() { - return extraLoadPath; - } - - public String getProgramFile() { - return programFile; - } - - public List getCommandLineScripts() { - return commandLineScripts; - } - - public List getProgramArgs() { - return programArgs; - } - - public List getSwitchArgs() { - return switchArgs; - } - - public int getRecordSeparator() { - return recordSeparator; - } - - public String getAutosplitPattern() { - return autosplitPattern; - } - - public boolean isAutosplit() { - return autosplit; - } - - public boolean isCheckSyntaxOnly() { - return checkSyntaxOnly; - } - - public boolean isLineEndingProcessing() { - return lineEndingProcessing; - } - - public boolean isInPlaceEdit() { - return inPlaceEdit; - } - - public String getInPlaceBackupExtension() { - return inPlaceBackupExtension; - } - - public boolean isImplicitLoop() { - return implicitLoop; - } - - public boolean isImplicitSedLoop() { - return implicitSedLoop; - } - - public boolean isImportFromPath() { - return importFromPath; - } - - public boolean isStripMessage() { - return stripMessage; - } - - public boolean useJLine() { - return useJLine; - } - - public Configuration getConfiguration() { - return configuration; - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.shell/src/com/oracle/truffle/ruby/shell/CommandLineParser.java --- a/graal/com.oracle.truffle.ruby.shell/src/com/oracle/truffle/ruby/shell/CommandLineParser.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,360 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.shell; - -import java.io.*; -import java.util.*; - -import com.oracle.truffle.ruby.runtime.configuration.*; - -/** - * MRI-compatible command line parser, producing {@link CommandLineOptions}. - */ -public abstract class CommandLineParser { - - /** - * Parse an MRI-compatible command line. - */ - public static CommandLineOptions parse(String[] args) { - assert args != null; - - final List preRequires = new ArrayList<>(); - String preChangeDirectory = null; - - final List extraLoadPath = new ArrayList<>(); - - String programFile = null; - final List commandLineScripts = new ArrayList<>(); - final List programArgs = new ArrayList<>(); - final List switchArgs = new ArrayList<>(); - - int recordSeparator = -1; - boolean autosplit = false; - String autosplitPattern = null; - boolean checkSyntaxOnly = false; - boolean lineEndingProcessing = false; - boolean inPlaceEdit = false; - String inPlaceBackupExtension = null; - boolean implicitLoop = false; - boolean implicitSedLoop = false; - boolean importFromPath = false; - boolean messageStrip = false; - boolean useJLine = true; - - final ConfigurationBuilder configurationBuilder = new ConfigurationBuilder(); - - final List normalizedArgs = normalizeArgs(args); - - boolean stillRubyArgs = true; - boolean collectingSwitchArgs = false; - int n = 0; - - while (n < normalizedArgs.size()) { - final String arg = normalizedArgs.get(n); - - if (stillRubyArgs && arg.startsWith("-")) { - if (collectingSwitchArgs) { - switchArgs.add(arg); - } else if (arg.startsWith("-0")) { - if (arg.length() == 2) { - recordSeparator = 0; - } else { - recordSeparator = Integer.parseInt(arg.substring(2), 8); - } - } else if (arg.startsWith("-i")) { - inPlaceEdit = true; - - if (arg.length() > 2) { - inPlaceBackupExtension = arg.substring(2); - } - } else if (arg.startsWith("-W")) { - if (arg.length() == 2) { - configurationBuilder.setWarningLevel(2); - } else if (arg.startsWith("-Wlevel=")) { - configurationBuilder.setWarningLevel(Integer.parseInt(arg.substring("-Wlevel=".length()))); - } else { - throw new IllegalArgumentException("bad flag " + arg); - } - } else if (arg.startsWith("-T")) { - if (arg.length() == 2) { - configurationBuilder.setTaintCheckLevel(1); - } else if (arg.startsWith("-Tlevel=")) { - configurationBuilder.setTaintCheckLevel(Integer.parseInt(arg.substring("-Tlevel=".length()))); - } else { - throw new IllegalArgumentException("bad flag " + arg); - } - } else if (arg.startsWith("-x")) { - messageStrip = true; - - if (arg.length() > 2) { - preChangeDirectory = arg.substring(2); - } - } else { - switch (arg) { - case "-C": - case "-e": - case "-E": - case "-F": - case "-I": - case "-r": - case "--home": - if (n + 1 >= normalizedArgs.size()) { - throw new RuntimeException("Expecting value after " + arg); - } - } - - switch (arg) { - case "--": - stillRubyArgs = false; - break; - case "-a": - autosplit = true; - break; - case "-c": - checkSyntaxOnly = true; - break; - case "-C": - if (n + 1 >= normalizedArgs.size()) { - throw new RuntimeException("Need a directory path after -C"); - } - preChangeDirectory = normalizedArgs.get(n + 1); - n++; - break; - case "-d": - case "--debug": - configurationBuilder.setDebug(true); - break; - case "--no-debug": - configurationBuilder.setDebug(false); - break; - case "--trace": - configurationBuilder.setTrace(true); - break; - case "--no-trace": - configurationBuilder.setTrace(false); - break; - case "-e": - commandLineScripts.add(normalizedArgs.get(n + 1)); - n++; - break; - case "-E": - final String[] encodings = normalizedArgs.get(n + 1).split(":"); - configurationBuilder.setDefaultExternalEncoding(encodings[0]); - - if (encodings.length == 2) { - configurationBuilder.setDefaultInternalEncoding(encodings[1]); - } else { - throw new IllegalArgumentException("bad flag " + arg); - } - - n++; - break; - case "-F": - autosplitPattern = normalizedArgs.get(n + 1); - n++; - break; - case "-I": - extraLoadPath.add(normalizedArgs.get(n + 1)); - n++; - break; - case "-l": - lineEndingProcessing = true; - break; - case "-n": - implicitLoop = true; - break; - case "-r": - preRequires.add(normalizedArgs.get(n + 1)); - n++; - break; - case "-s": - collectingSwitchArgs = true; - break; - case "-p": - implicitSedLoop = true; - break; - case "-S": - importFromPath = true; - break; - case "-w": - configurationBuilder.setWarningLevel(1); - break; - case "-h": - case "--help": - help(System.out); - return null; - case "-v": - version(System.out); - configurationBuilder.setVerbose(true); - break; - case "--version": - version(System.out); - return null; - case "--copyright": - copyright(System.out); - return null; - case "--home": - configurationBuilder.setStandardLibrary(normalizedArgs.get(n + 1) + "/" + ConfigurationBuilder.JRUBY_STDLIB_JAR); - n++; - break; - case "--stdlib": - configurationBuilder.setStandardLibrary(normalizedArgs.get(n + 1)); - n++; - break; - case "--full-object-space": - configurationBuilder.setFullObjectSpace(true); - break; - case "--no-jline": - useJLine = false; - break; - case "--print-parse-tree": - configurationBuilder.setPrintParseTree(true); - break; - case "--print-uninitialized-calls": - configurationBuilder.setPrintUninitializedCalls(true); - break; - case "--print-java-exceptions": - configurationBuilder.setPrintJavaExceptions(true); - break; - default: - throw new IllegalArgumentException("unknown flag " + arg); - } - } - } else if (programFile == null) { - programFile = arg; - stillRubyArgs = false; - } else { - programArgs.add(arg); - } - - n++; - } - - return new CommandLineOptions(preRequires, preChangeDirectory, extraLoadPath, programFile, commandLineScripts, programArgs, switchArgs, recordSeparator, autosplit, autosplitPattern, - checkSyntaxOnly, lineEndingProcessing, inPlaceEdit, inPlaceBackupExtension, implicitLoop, implicitSedLoop, importFromPath, messageStrip, useJLine, new Configuration( - configurationBuilder)); - } - - /** - * Produce a canonical set of arguments that includes {@code $RUBYOPT} and has contractions such - * as a {@code -rdir} replaced with separate arguments {@code -r} and {@code dir} for simpler - * processing. - */ - private static List normalizeArgs(String[] args) { - assert args != null; - - // Arguments come from the main method arguments parameter and $RUBYOPT - - final List inputArgs = new ArrayList<>(); - - final String rubyoptVar = System.getenv("RUBYOPT"); - - if (rubyoptVar != null) { - /* - * TODO(cs): what we've got here is a string that we are supposed to treat as if it was - * an extra part of the command line, including more Ruby options. However, we just get - * the string and have to split it into arguments ourselves. Normally the shell does - * that, including lots of fancy quoting styles. Are we supposed to re-implement all of - * that? Otherwise arguments in RUBYOPT will be parsed differently to if they were - * actually on the command line. JRuby just splits like we do. I also think that's what - * MRI does, but is this correct? - */ - - inputArgs.addAll(Arrays.asList(rubyoptVar.split("\\s+"))); - } - - inputArgs.addAll(Arrays.asList(args)); - - // Replace some contractions such as -rdir with -r dir - - final List outputArgs = new ArrayList<>(); - - for (String arg : inputArgs) { - if (arg.startsWith("-C") || arg.startsWith("-E") || arg.startsWith("-F") || arg.startsWith("-I") || arg.startsWith("-r")) { - outputArgs.add(arg.substring(0, 2)); - outputArgs.add(arg.substring(2)); - } else { - outputArgs.add(arg); - } - } - - return outputArgs; - } - - /** - * Print help information. - */ - private static void help(PrintStream out) { - out.println("Usage: ruby [switches] [--] [programfile] [arguments]"); - out.println(" -0[octal] specify record separator (\0, if no argument)"); - out.println(" -a autosplit mode with -n or -p (splits $_ into $F)"); - out.println(" -c check syntax only"); - out.println(" -Cdirectory cd to directory, before executing your script"); - out.println(" -d, --debug set debugging flags (set $DEBUG to true) and enable Debug module"); - out.println(" -e 'command' one line of script. Several -e's allowed. Omit [programfile]"); - out.println(" -Eex[:in] specify the default external and internal character encodings"); - out.println(" -Fpattern split() pattern for autosplit (-a)"); - out.println(" -i[extension] edit ARGV files in place (make backup if extension supplied)"); - out.println(" -Idirectory specify $LOAD_PATH directory (may be used more than once)"); - out.println(" -l enable line ending processing"); - out.println(" -n assume 'while gets(); ... end' loop around your script"); - out.println(" -p assume loop like -n but print line also like sed"); - out.println(" -rlibrary require the library, before executing your script"); - out.println(" -s enable some switch parsing for switches after script name"); - out.println(" -S look for the script using PATH environment variable"); - out.println(" -T[level=1] turn on tainting checks"); - out.println(" -v print version number, then turn on verbose mode"); - out.println(" -w turn warnings on for your script"); - out.println(" -W[level=2] set warning level; 0=silence, 1=medium, 2=verbose"); - out.println(" -x[directory] strip off text before #!ruby line and perhaps cd to directory"); - out.println(" --copyright print the copyright"); - out.println(" --version print the version"); - out.println("Extra rubytruffle switches:"); - out.println(" --home dir set the location of the Ruby Truffle installation (default . or $RUBY_TRUFFLE_HOME)"); - out.println(" --stdlib dir use a directory for the Ruby standard library"); - out.println(" --full-object-space enable full ObjectSpace#each_object and similar"); - out.println(" --no-debug disable debugging"); - out.println(" --no-trace disable tracing"); - out.println("Debugging rubytruffle switches:"); - out.println(" --no-cache-constant-lookup don't cache constant lookups"); - out.println(" --no-cache-method-calls don't cache method lookups"); - out.println(" --no-intrinsic-method-calls don't turn method calls into intrinsic nodes"); - out.println(" --no-jline don't use JLine"); - out.println(" --print-parse-tree print the result of parsing"); - out.println(" --print-uninitialized-calls print each time a method call is uninitialized"); - out.println(" --print-java-exceptions print Java exception back traces at the point of translating them to Ruby exceptions"); - out.println("Relevant environment variables:"); - out.println(" RUBYHOME location of the Ruby Truffle installation"); - out.println(" RUBYOPT extra command line arguments"); - out.println(" RUBYLIB list of colon separated paths to add to $LOAD_PATH"); - out.println(" PATH as RUBYLIB, if -S is used"); - } - - /** - * Print version information. - */ - private static void version(PrintStream out) { - out.printf("ruby (rubytruffle) dev [JVM %s]\n", System.getProperty("java.version")); - } - - /** - * Print copyright information. - */ - private static void copyright(PrintStream out) { - out.println("Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved. This"); - out.println("code is released under a tri EPL/GPL/LGPL license. You can use it,"); - out.println("redistribute it and/or modify it under the terms of the:"); - out.println(); - out.println("Eclipse Public License version 1.0"); - out.println("GNU General Public License version 2"); - out.println("GNU Lesser General Public License version 2.1"); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.shell/src/com/oracle/truffle/ruby/shell/Shell.java --- a/graal/com.oracle.truffle.ruby.shell/src/com/oracle/truffle/ruby/shell/Shell.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,212 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.shell; - -import java.io.*; - -import jline.console.*; - -import com.oracle.truffle.api.*; -import com.oracle.truffle.ruby.nodes.core.*; -import com.oracle.truffle.ruby.parser.*; -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.configuration.*; -import com.oracle.truffle.ruby.runtime.core.array.*; - -/** - * The entry point class for RubyTruffle. Implements the MRI command line interface. - */ -public class Shell { - - /** - * Entry point method for Ruby both in batch and interactive mode. - */ - public static void main(String[] args) throws IOException { - // Parse the command line - - final CommandLineOptions options = CommandLineParser.parse(args); - - if (options == null) { - return; - } - - // Setup JLine - - ConsoleReader console = null; - - if (options.useJLine()) { - System.setProperty("jline.shutdownhook", "true"); - console = new ConsoleReader(); - console.setExpandEvents(false); - } - - // Override the home directory if RUBYHOME is set - - final ConfigurationBuilder configurationBuilder = new ConfigurationBuilder(options.getConfiguration()); - - if (System.getenv("RUBYHOME") != null) { - configurationBuilder.setStandardLibrary(System.getenv("RUBYHOME") + "/" + ConfigurationBuilder.JRUBY_STDLIB_JAR); - } - - // Use JLine for console input - - final ConsoleReader finalConsole = console; - - if (options.useJLine()) { - configurationBuilder.setInputReader(new InputReader() { - - @Override - public String readLine(String prompt) throws IOException { - return finalConsole.readLine(prompt); - } - - }); - } - - // Set up a context - - final RubyContext context = new RubyContext(new Configuration(configurationBuilder), new JRubyParser()); - - // Bring in core method nodes - - CoreMethodNodeManager.addMethods(context.getCoreLibrary().getObjectClass()); - - // Give the core library manager a chance to tweak some of those methods - - context.getCoreLibrary().initializeAfterMethodsAdded(); - - // Set program arguments - - for (String arg : options.getProgramArgs()) { - context.getCoreLibrary().getArgv().push(context.makeString(arg)); - } - - if (!options.getSwitchArgs().isEmpty()) { - context.implementationMessage("can't set -s switch arguments yet"); - } - - // Set the load path - - final RubyArray loadPath = (RubyArray) context.getCoreLibrary().getGlobalVariablesObject().getInstanceVariable("$:"); - - final String pathVar = System.getenv("PATH"); - - if (options.isImportFromPath() && pathVar != null) { - for (String path : pathVar.split(File.pathSeparator)) { - loadPath.push(context.makeString(path)); - } - } - - for (String path : options.getExtraLoadPath()) { - loadPath.push(context.makeString(path)); - } - - final String rubylibVar = System.getenv("RUBYLIB"); - - if (rubylibVar != null) { - for (String path : rubylibVar.split(File.pathSeparator)) { - loadPath.push(context.makeString(path)); - } - } - - if (context.getConfiguration().getStandardLibrary().endsWith(".jar")) { - /* - * Use the 1.9 library, even though we're emulating 2.1, as there are some bugs running - * the 2.1 library at the moment. - */ - loadPath.push(context.makeString("jar:file:" + context.getConfiguration().getStandardLibrary() + "!/META-INF/jruby.home/lib/ruby/1.9")); - } else { - loadPath.push(context.makeString(context.getConfiguration().getStandardLibrary())); - } - - // Pre-required modules - - for (String feature : options.getPreRequires()) { - context.getFeatureManager().require(feature); - } - - // Check for other options that are not implemented yet - - if (options.getRecordSeparator() != -1) { - context.implementationMessage("record separator not implemented"); - } - - if (options.isAutosplit()) { - context.implementationMessage("autosplit not implemented"); - } - - if (options.getPreChangeDirectory() != null) { - context.implementationMessage("not able to change directory"); - } - - if (options.isLineEndingProcessing()) { - context.implementationMessage("line end processing not implemented"); - } - - if (options.isInPlaceEdit()) { - context.implementationMessage("in place editing not implemented"); - } - - if (options.isImplicitLoop() || options.isImplicitSedLoop()) { - context.implementationMessage("implicit loops not implemented"); - } - - if (options.isStripMessage()) { - context.implementationMessage("strip message -x option not implemented"); - } - - // Run the scripts, program file, or run the temporary version of IRB - - try { - if (!options.getCommandLineScripts().isEmpty()) { - final StringBuilder combinedScript = new StringBuilder(); - - for (String script : options.getCommandLineScripts()) { - combinedScript.append(script); - combinedScript.append("\n"); - } - - try { - final Source source = context.getSourceManager().get("-e", combinedScript.toString()); - if (options.isCheckSyntaxOnly()) { - context.getParser().parse(context, source, RubyParser.ParserContext.TOP_LEVEL, null); - System.out.println("Syntax OK"); - } else { - context.execute(context, source, RubyParser.ParserContext.TOP_LEVEL, context.getCoreLibrary().getMainObject(), null); - } - } catch (Exception e) { - e.printStackTrace(); - } - } else if (options.getProgramFile() != null) { - try { - if (options.isCheckSyntaxOnly()) { - final Source source = context.getSourceManager().get(options.getProgramFile()); - context.getParser().parse(context, source, RubyParser.ParserContext.TOP_LEVEL, null); - System.out.println("Syntax OK"); - } else { - context.loadFile(options.getProgramFile()); - } - } catch (Exception e) { - e.printStackTrace(); - } - } else { - if (options.isCheckSyntaxOnly()) { - System.err.println("Can't check syntax in IRB mode"); - return; - } - - context.runShell(null, null); - } - } finally { - context.shutdown(); - } - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/README --- a/graal/com.oracle.truffle.ruby.test/specs/README Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,21 +0,0 @@ -This is a configuration of the RubySpec set of specifications - -http://rubyspec.org. RubySpec is the specifications, and MSpec is the tool to -run them. - -Thanks to Brian Shirai and others who have worked on RubySpec. - -At the moment we have only configured the version 1.9 specs, and we only run -language and command line specs. - -In the `specs` directory (everything we do here will be in the `specs` -directory), you need to clone the MSpec and RubySpec Git repositories: - - $ git clone https://github.com/rubyspec/mspec.git - $ git --git-dir=mspec/.git --work-tree=mspec checkout 1343524a06466b7aa0c90798b7894454c8abce0f - $ git clone https://github.com/rubyspec/rubyspec.git - $ git --git-dir=rubyspec/.git --work-tree=rubyspec checkout 926e356b268fe32c67bec43a21565d727360a89b - -Then you can run MSpec to run RubySpec. We can run all of the harness in our -implementation, not just as an executable under test. - - $ ./rubytruffle mspec/bin/mspec run -t ./rubytruffle --config rubytruffle.mspec --excl-tag fails diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/rubytruffle --- a/graal/com.oracle.truffle.ruby.test/specs/rubytruffle Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,20 +0,0 @@ -#!/bin/bash - -# The command this file executes is what mx would execute, just taken out of -# the mx wrapper because it appears to interfere with MSpec, and we need a -# 'executable' (a shell script will do) to run. -# -# If this file isn't working for you try generating one for your setup. You -# will need to do this for example if your Java isn't 1.7.0u45. You can use -# the command below - the -v flag gives you the Java command, then just append -# "$@". -# -# $GRAAL_DIR/mxtool/mx -v --vm server-nograal ruby -ea -- --home $GRAAL_DIR "$@" - -GRAAL_DIR=../../.. - -$GRAAL_DIR/jdk1.7.0_45/product/bin/java \ - -server-nograal -d64 -ea \ - -cp $GRAAL_DIR/lib/jline-2.10.jar:$GRAAL_DIR/lib/jrubyparser-0.5.0.jar:$GRAAL_DIR/lib/jruby-stdlib-1.7.4.jar:$GRAAL_DIR/lib/jnr-posix-3.0.0.jar:$GRAAL_DIR/lib/jnr-constants-0.8.4.jar:$GRAAL_DIR/lib/jnr-ffi-1.0.4.jar:$GRAAL_DIR/lib/jffi-1.2.1.jar:$GRAAL_DIR/lib/jffi-1.2.1-native.jar:$GRAAL_DIR/lib/jnr-x86asm-1.0.2.jar:$GRAAL_DIR/lib/asm-4.0.jar:$GRAAL_DIR/lib/asm-analysis-4.0.jar:$GRAAL_DIR/lib/asm-commons-4.0.jar:$GRAAL_DIR/lib/asm-tree-4.0.jar:$GRAAL_DIR/lib/asm-util-4.0.jar:$GRAAL_DIR/graal/com.oracle.truffle.api/bin:$GRAAL_DIR/graal/com.oracle.truffle.ruby.runtime/bin:$GRAAL_DIR/graal/com.oracle.truffle.api.dsl/bin:$GRAAL_DIR/graal/com.oracle.truffle.ruby.nodes/bin:$GRAAL_DIR/graal/com.oracle.truffle.ruby.parser/bin:$GRAAL_DIR/graal/com.oracle.truffle.ruby.shell/bin \ - com.oracle.truffle.ruby.shell.Shell \ - --home $GRAAL_DIR "$@" diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/rubytruffle.mspec --- a/graal/com.oracle.truffle.ruby.test/specs/rubytruffle.mspec Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,26 +0,0 @@ -class MSpecScript - - Rubyspec = "rubyspec" - - set :command_line, [ - "rubyspec/command_line" - ] - - set :language, [ - "rubyspec/language" - ] - - set :tags_patterns, [ - [/rubyspec/, "tags"], - [/_spec.rb$/, "_tags.txt"] - ] - - MSpec.enable_feature :encoding - MSpec.enable_feature :continuation - MSpec.enable_feature :fiber - MSpec.enable_feature :fork - MSpec.enable_feature :generator - - set :files, get(:command_line) + get(:language) - -end diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_a_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_a_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2 +0,0 @@ -fails:The -a command line option runs the code in loop conditional on Kernel.gets() -fails:The -a command line option sets $-a diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_d_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_d_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,3 +0,0 @@ -fails:The -d command line option sets $DEBUG to true -fails:The -d command line option sets $VERBOSE to true -fails:The -d command line option sets $-d to true diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_e_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_e_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2 +0,0 @@ -fails:The -e command line option with -n and a Fixnum range mimics an awk conditional by comparing an inclusive-end range with $. -fails:The -e command line option with -n and a Fixnum range mimics a sed conditional by comparing an exclusive-end range with $. diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_n_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_n_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,4 +0,0 @@ -fails:The -n command line option runs the code in loop conditional on Kernel.gets() -fails:The -n command line option only evaluates BEGIN blocks once -fails:The -n command line option only evaluates END blocks once -fails:The -n command line option allows summing over a whole file diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_p_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_p_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2 +0,0 @@ -fails:The -p command line option runs the code in loop conditional on Kernel.gets() and prints $_ -fails:The -p command line option sets $-p diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_r_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_r_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -fails:The -r command line option requires the specified file diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_s_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_s_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,8 +0,0 @@ -fails:The -s command line option when using -- to stop parsing sets the value to true without an explicit value -fails:The -s command line option when using -- to stop parsing parses single letter args into globals -fails:The -s command line option when using -- to stop parsing parses long args into globals -fails:The -s command line option when using -- to stop parsing converts extra dashes into underscores -fails:The -s command line option when running a script sets the value to true without an explicit value -fails:The -s command line option when running a script parses single letter args into globals -fails:The -s command line option when running a script parses long args into globals -fails:The -s command line option when running a script converts extra dashes into underscores diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_upper_e_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_upper_e_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -fails:ruby -E raises a RuntimeError if used with -U diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_upper_f_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_upper_f_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -fails:the -F command line option specifies the field separator pattern for -a diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_upper_i_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_upper_i_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -fails:The -I command line option adds the path to the load path ($:) diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_upper_u_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_upper_u_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,7 +0,0 @@ -fails:ruby -U sets Encoding.default_internal to UTF-8 -fails:ruby -U does nothing different if specified multiple times -fails:ruby -U is overruled by Encoding.default_internal= -fails:ruby -U does not affect the default external encoding -fails:ruby -U does not affect the source encoding -fails:ruby -U raises a RuntimeError if used with -Eext:int -fails:ruby -U raises a RuntimeError if used with -E:int diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_upper_w_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_upper_w_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,3 +0,0 @@ -fails:The -W command line option with 0 sets $VERBOSE to nil -fails:The -W command line option with 1 sets $VERBOSE to false -fails:The -W command line option with 2 sets $VERBOSE to true diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_v_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_v_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -fails:The -v command line option sets $VERBOSE to true diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_w_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_w_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -fails:The -w command line option sets $VERBOSE to true diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_x_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/command_line/dash_x_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2 +0,0 @@ -fails:The -x command line option runs code after the first /#!.*ruby.*/-ish line in target file -fails:The -x command line option needs to be reviewed for spec completeness diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/command_line/error_message_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/command_line/error_message_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -fails:The error message caused by an exception is not printed to stdout diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/language/BEGIN_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/BEGIN_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,4 +0,0 @@ -fails:The BEGIN keyword runs first in a given code unit -fails:The BEGIN keyword runs multiple begins in FIFO order -fails:The BEGIN keyword runs in a shared scope -fails:The BEGIN keyword accesses variables outside the eval scope diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/language/alias_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/alias_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,11 +0,0 @@ -fails:The alias keyword creates a new name for an existing method -fails:The alias keyword adds the new method to the list of methods -fails:The alias keyword adds the new method to the list of public methods -fails:The alias keyword overwrites an existing method with the target name -fails:The alias keyword is reversible -fails:The alias keyword operates on the object's metaclass when used in instance_eval -fails:The alias keyword operates on methods with splat arguments -fails:The alias keyword operates on methods with splat arguments on eigenclasses -fails:The alias keyword operates on methods with splat arguments defined in a superclass -fails:The alias keyword operates on methods with splat arguments defined in a superclass using text block for class eval -fails:The alias keyword is not allowed against Fixnum or String instances diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/language/array_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/array_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,4 +0,0 @@ -fails:The unpacking splat operator (*) returns a new array containing the same values when applied to an array inside an empty array -fails:The unpacking splat operator (*) unpacks the start and count arguments in an array slice assignment -fails:Array literals [] treats splatted nil as no element -fails:The unpacking splat operator (*) when applied to a non-Array value attempts to coerce it to Array if the object respond_to?(:to_a) diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/language/block_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/block_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,67 +0,0 @@ -fails:A block allows to define a block variable with the same name as the enclosing block -fails:A block taking |a| arguments assigns nil to the argument when no values are yielded -fails:A block taking |a| arguments does not call #to_ary to convert a single yielded object to an Array -fails:A block taking |a| arguments assigns the first value yielded to the argument -fails:A block taking |a, b| arguments assgins nil to the arguments when no values are yielded -fails:A block taking |a, b| arguments assigns one value yielded to the first argument -fails:A block taking |a, b| arguments destructures a splatted Array -fails:A block taking |a, b| arguments calls #to_ary to convert a single yielded object to an Array -fails:A block taking |a, b| arguments does not call #to_ary if the single yielded object is an Array -fails:A block taking |a, b| arguments does not call #to_ary if the object does not respond to #to_ary -fails:A block taking |a, b| arguments raises an TypeError if #to_ary does not return an Array -fails:A block taking |a, *b| arguments assigns 'nil' and '[]' to the arguments when no values are yielded -fails:A block taking |a, *b| arguments assigns all yielded values after the first to the rest argument -fails:A block taking |a, *b| arguments assigns 'nil' and '[]' to the arguments when a single, empty Array is yielded -fails:A block taking |a, *b| arguments assigns the element of a single element Array to the first argument -fails:A block taking |a, *b| arguments destructures a splatted Array -fails:A block taking |a, *b| arguments destructures a single Array value assigning the remaining values to the rest argument -fails:A block taking |a, *b| arguments calls #to_ary to convert a single yielded object to an Array -fails:A block taking |a, *b| arguments does not call #to_ary if the single yielded object is an Array -fails:A block taking |a, *b| arguments raises an TypeError if #to_ary does not return an Array -fails:A block taking |*| arguments does not call #to_ary if the single yielded object is an Array -fails:A block taking |*| arguments does not call #to_ary to convert a single yielded object to an Array -fails:A block taking |*a| arguments assigns all the values passed to the argument as an Array -fails:A block taking |*a| arguments assigns '[[]]' to the argument when passed an empty Array -fails:A block taking |*a| arguments assigns a single Array value passed to the argument by wrapping it in an Array -fails:A block taking |*a| arguments does not call #to_ary if the single yielded object is an Array -fails:A block taking |*a| arguments does not call #to_ary to convert a single yielded object to an Array -fails:A block taking |a, | arguments assigns nil to the argument when no values are yielded -fails:A block taking |a, | arguments assigns the argument the first value yielded -fails:A block taking |a, | arguments assigns the argument the first of several values yielded when it is an Array -fails:A block taking |a, | arguments assigns nil to the argument when passed an empty Array -fails:A block taking |a, | arguments assigns the argument the first element of the Array when passed a single Array -fails:A block taking |a, | arguments calls #to_ary to convert a single yielded object to an Array -fails:A block taking |a, | arguments does not call #to_ary if the single yielded object is an Array -fails:A block taking |a, | arguments raises an TypeError if #to_ary does not return an Array -fails:A block taking |(a, b)| arguments assigns nil to the arguments when yielded no values -fails:A block taking |(a, b)| arguments calls #to_ary to convert a single yielded object to an Array -fails:A block taking |(a, b)| arguments does not call #to_ary if the single yielded object is an Array -fails:A block taking |(a, b)| arguments does not call #to_ary if the object does not respond to #to_ary -fails:A block taking |(a, b)| arguments raises an TypeError if #to_ary does not return an Array -fails:A block taking |(a, b), c| arguments assigns nil to the arguments when yielded no values -fails:A block taking |(a, b), c| arguments destructures a single one-level Array value yielded -fails:A block taking |(a, b), c| arguments destructures a single multi-level Array value yielded -fails:A block taking |(a, b), c| arguments calls #to_ary to convert a single yielded object to an Array -fails:A block taking |(a, b), c| arguments does not call #to_ary if the single yielded object is an Array -fails:A block taking |(a, b), c| arguments does not call #to_ary if the object does not respond to #to_ary -fails:A block taking |(a, b), c| arguments raises an TypeError if #to_ary does not return an Array -fails:A block taking nested |a, (b, (c, d))| destructures a single multi-level Array value yielded -fails:A block taking nested |a, (b, (c, d))| destructures a single multi-level Array value yielded -fails:A block taking nested |a, ((b, c), d)| destructures a single multi-level Array value yielded -fails:A block taking nested |a, ((b, c), d)| destructures a single multi-level Array value yielded -fails:A block arguments with _ extracts arguments with _ -fails:Block-local variables override shadowed variables from the outer scope -fails:Post-args appear after a splat -fails:Post-args are required -fails:Post-args with required args gathers remaining args in the splat -fails:Post-args with required args has an empty splat when there are no remaining args -fails:Post-args with optional args gathers remaining args in the splat -fails:Post-args with optional args overrides the optional arg before gathering in the splat -fails:Post-args with optional args uses the required arg before the optional and the splat -fails:Post-args with optional args overrides the optional args from left to right before gathering the splat -fails:A block taking |(a, b)| arguments destructures a single Array value yielded -fails:A block taking |(a, b)| arguments destructures a single Array value yielded when shadowing an outer variable -fails:A block taking nested |a, (b, (c, d))| assigns nil to the arguments when yielded no values -fails:A block taking nested |a, (b, (c, d))| destructures separate yielded values -fails:A block taking nested |a, ((b, c), d)| assigns nil to the arguments when yielded no values -fails:A block taking nested |a, ((b, c), d)| destructures separate yielded values diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/language/break_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/break_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,3 +0,0 @@ -fails:The break statement in a lambda created at the toplevel returns a value when invoking from the toplevel -fails:The break statement in a lambda created at the toplevel returns a value when invoking from a method -fails:The break statement in a lambda created at the toplevel returns a value when invoking from a block diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/language/case_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/case_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,12 +0,0 @@ -fails:The 'case'-construct evaluates the body of the when clause matching the case target expression -fails:The 'case'-construct evaluates the body of the when clause whose array expression includes the case target expression -fails:The 'case'-construct evaluates the body of the when clause in left-to-right order if it's an array expression -fails:The 'case'-construct evaluates the body of the when clause whose range expression includes the case target expression -fails:The 'case'-construct expands arrays to lists of values -fails:The 'case'-construct concats arrays before expanding them -fails:The 'case'-construct never matches when clauses with no values -fails:The 'case'-construct works even if there's only one when statement -fails:The 'case'-construct with no target expression evaluates true as only 'true' when true is the first clause -fails:The 'case'-construct with no target expression evaluates false as only 'false' when false is the first clause -fails:The 'case'-construct with no target expression treats a literal array as its own when argument, rather than a list of arguments -fails:The 'case'-construct takes multiple expanded arrays diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/language/class_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/class_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,18 +0,0 @@ -fails:A class definition has no class variables -fails:A class definition raises TypeError if the constant qualifying the class is nil -fails:A class definition raises TypeError if any constant qualifying the class is not a Module -fails:A class definition allows using self as the superclass if self is a class -fails:A class definition raises a TypeError if inheriting from a metaclass -fails:A class definition allows the declaration of class variables in the body -fails:A class definition stores instance variables defined in the class body in the class object -fails:A class definition allows the declaration of class variables in a class method -fails:A class definition allows the definition of class-level instance variables in a class method -fails:A class definition allows the declaration of class variables in an instance method -fails:A class definition returns the value of the last statement in the body -fails:An outer class definition contains the inner classes -fails:A class definition extending an object (sclass) raises a TypeError when trying to extend numbers -fails:A class definition extending an object (sclass) allows accessing the block of the original scope -fails:A class definition extending an object (sclass) can use return to cause the enclosing method to return -fails:Reopening a class raises a TypeError when superclasses mismatch -fails:Reopening a class adds new methods to subclasses -fails:class provides hooks calls inherited when a class is created diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/language/class_variable_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/class_variable_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,10 +0,0 @@ -fails:A class variable can be accessed from a subclass -fails:A class variable is set in the superclass -fails:A class variable defined in a module can be accessed from classes that extend the module -fails:A class variable defined in a module is not defined in these classes -fails:A class variable defined in a module is only updated in the module a method defined in the module is used -fails:A class variable defined in a module is updated in the class when a Method defined in the class is used -fails:A class variable defined in a module can be accessed from modules that extend the module -fails:A class variable defined in a module is defined in the extended module -fails:A class variable defined in a module is not defined in the extending module -fails:A class variable defined in a module can be accessed inside the class using the module methods diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/language/constants_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/constants_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -fails:Literal (A::X) constant resolution sends #const_missing to the original class or module scope -fails:Literal (A::X) constant resolution raises a TypeError if a non-class or non-module qualifier is given -fails:Literal (A::X) constant resolution with statically assigned constants does not search the singleton class of the class or module -fails:Literal (A::X) constant resolution with dynamically assigned constants does not search the singleton class of the class or module -fails:Literal (A::X) constant resolution with dynamically assigned constants evaluates the right hand side before evaluating a constant path -fails:Constant resolution within methods sends #const_missing to the original class or module scope -fails:Constant resolution within methods with statically assigned constants searches the lexical scope of the method not the receiver's immediate class -fails:Constant resolution within methods with statically assigned constants searches the lexical scope of a singleton method -fails:Constant resolution within methods with statically assigned constants searches Object as a lexical scope only if Object is explicitly opened -fails:Constant resolution within methods with dynamically assigned constants searches the immediate class or module scope first -fails:Constant resolution within methods with dynamically assigned constants searches the superclass before a module included in the superclass -fails:Constant resolution within methods with dynamically assigned constants searches the lexical scope of the method not the receiver's immediate class -fails:Constant resolution within methods with dynamically assigned constants searches the lexical scope of a singleton method -fails:Constant resolution within methods with dynamically assigned constants does not search the lexical scope of the caller -fails:Constant resolution within methods with dynamically assigned constants searches the lexical scope of a block -fails:Constant resolution within methods with dynamically assigned constants searches Object as a lexical scope only if Object is explicitly opened -fails:Constant resolution within methods with ||= assignes constant if previously undefined -fails:Module#private_constant marked constants remain private even when updated -fails:Module#private_constant marked constants in a module cannot be accessed from outside the module -fails:Module#private_constant marked constants in a module cannot be reopened as a module -fails:Module#private_constant marked constants in a module cannot be reopened as a class -fails:Module#private_constant marked constants in a module is not defined? with A::B form -fails:Module#private_constant marked constants in a module can be accessed from lexical scope -fails:Module#private_constant marked constants in a module is defined? from lexical scope -fails:Module#private_constant marked constants in a class cannot be accessed from outside the class -fails:Module#private_constant marked constants in a class cannot be reopened as a module -fails:Module#private_constant marked constants in a class cannot be reopened as a class -fails:Module#private_constant marked constants in a class is not defined? with A::B form -fails:Module#private_constant marked constants in a class can be accessed from lexical scope -fails:Module#private_constant marked constants in Object cannot be accessed using ::Const form -fails:Module#private_constant marked constants in Object is not defined? using ::Const form -fails:Module#public_constant marked constants in a module can be accessed from outside the module -fails:Module#public_constant marked constants in a module is defined? with A::B form -fails:Module#public_constant marked constants in a class can be accessed from outside the class -fails:Module#public_constant marked constants in a class is defined? with A::B form -fails:Module#public_constant marked constants in Object can be accessed using ::Const form -fails:Module#public_constant marked constants in Object is defined? using ::Const form -fails:Module#private_constant marked constants in a class is defined? from lexical scope -fails:Literal (A::X) constant resolution with statically assigned constants searches a module included in the superclass -fails:Constant resolution within methods with statically assigned constants searches a module included in the superclass -fails:Constant resolution within methods with statically assigned constants searches the superclass chain -fails:Literal (A::X) constant resolution with statically assigned constants searches Object if no class or module qualifier is given -fails:Literal (A::X) constant resolution with statically assigned constants searches Object after searching other scopes -fails:Constant resolution within methods with statically assigned constants searches the superclass chain -fails:Literal (A::X) constant resolution with statically assigned constants searches the superclass chain diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/language/def_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/def_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,28 +0,0 @@ -fails:Defining an 'initialize' method sets the method's visibility to private -fails:Defining an 'initialize_copy' method sets the method's visibility to private -fails:An instance method with a default argument assigns an empty Array to an unused splat argument -fails:An instance method with a default argument prefers to assign to a default argument when there are no required arguments -fails:An instance method with a default argument does not evaluate the default when passed a value and a * argument -fails:A singleton method definition raises RuntimeError if frozen -fails:Redefining a singleton method does not inherit a previously set visibility -fails:Redefining a singleton method does not inherit a previously set visibility -fails:A method defined with extreme default arguments may use an fcall as a default -fails:A method defined with extreme default arguments may use preceding arguments as defaults -fails:A method defined with extreme default arguments may use a lambda as a default -fails:A singleton method defined with extreme default arguments may use an fcall as a default -fails:A singleton method defined with extreme default arguments may use preceding arguments as defaults -fails:A singleton method defined with extreme default arguments may use a lambda as a default -fails:A method definition inside a metaclass scope can create a class method -fails:A method definition inside a metaclass scope can create a singleton method -fails:A method definition inside a metaclass scope raises RuntimeError if frozen -fails:A nested method definition creates an instance method when evaluated in an instance method -fails:A nested method definition creates a class method when evaluated in a class method -fails:A nested method definition creates a singleton method when evaluated in the metaclass of an instance -fails:A method definition inside an instance_eval creates a singleton method -fails:A method definition inside an instance_eval creates a singleton method when evaluated inside a metaclass -fails:A method definition inside an instance_eval creates a class method when the receiver is a class -fails:A method definition in an eval creates an instance method -fails:A method definition in an eval creates a class method -fails:A method definition in an eval creates a singleton method -fails:a method definition that sets more than one default parameter all to the same value assigns them all the same object by default -fails:The def keyword within a closure looks outside the closure for the visibility diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/language/defined_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/defined_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,48 +0,0 @@ -fails:The defined? keyword when called with a method name having a module as receiver returns nil if the method is private -fails:The defined? keyword when called with a method name having a module as receiver returns nil if the method is protected -fails:The defined? keyword when called with a method name having a local variable as receiver calls #respond_to_missing? -fails:The defined? keyword for an expression returns nil for an expression with !~ and an undefined method -fails:The defined? keyword for an expression returns 'method' for an expression with '!~' -fails:The defined? keyword for an expression with logical connectives returns nil for an expression with '!' and an unset class variable -fails:The defined? keyword for an expression with logical connectives returns nil for an expression with 'not' and an unset class variable -fails:The defined? keyword for an expression with logical connectives returns nil for an expression with '!' and an unset global variable -fails:The defined? keyword for an expression with logical connectives returns nil for an expression with '!' and an unset instance variable -fails:The defined? keyword for an expression with logical connectives returns nil for an expression with 'not' and an unset global variable -fails:The defined? keyword for an expression with logical connectives returns nil for an expression with 'not' and an unset instance variable -fails:The defined? keyword for variables returns nil for a global variable that has not been read -fails:The defined? keyword for variables returns nil for a global variable that has been read but not assigned to -fails:The defined? keyword for variables when a String does not match a Regexp returns nil for $& -fails:The defined? keyword for variables when a String does not match a Regexp returns nil for $` -fails:The defined? keyword for variables when a String does not match a Regexp returns nil for $' -fails:The defined? keyword for variables when a String does not match a Regexp returns nil for $+ -fails:The defined? keyword for variables when a String matches a Regexp returns 'global-variable' for $& -fails:The defined? keyword for variables when a String matches a Regexp returns 'global-variable' for $` -fails:The defined? keyword for variables when a String matches a Regexp returns 'global-variable' for $' -fails:The defined? keyword for variables when a String matches a Regexp returns 'global-variable' for $+ -fails:The defined? keyword for variables when a String matches a Regexp returns 'global-variable' for the capture references -fails:The defined? keyword for variables when a Regexp does not match a String returns nil for $& -fails:The defined? keyword for variables when a Regexp does not match a String returns nil for $` -fails:The defined? keyword for variables when a Regexp does not match a String returns nil for $' -fails:The defined? keyword for variables when a Regexp does not match a String returns nil for $+ -fails:The defined? keyword for variables when a Regexp matches a String returns 'global-variable' for $& -fails:The defined? keyword for variables when a Regexp matches a String returns 'global-variable' for $` -fails:The defined? keyword for variables when a Regexp matches a String returns 'global-variable' for $' -fails:The defined? keyword for variables when a Regexp matches a String returns 'global-variable' for $+ -fails:The defined? keyword for variables when a Regexp matches a String returns 'global-variable' for the capture references -fails:The defined? keyword for a scoped constant returns nil when an undefined constant is scoped to a defined constant -fails:The defined? keyword for a top-level scoped constant returns nil when an undefined constant is scoped to a defined constant -fails:The defined? keyword for super returns nil when a superclass undef's the method -fails:The defined? keyword for super for a method taking no arguments returns 'super' from a block when a superclass method exists -fails:The defined? keyword for super for a method taking no arguments returns 'super' from a #define_method when a superclass method exists -fails:The defined? keyword for super for a method taking no arguments returns 'super' from a block in a #define_method when a superclass method exists -fails:The defined? keyword for super for a method taking no arguments returns 'super' when the method exists in a supermodule -fails:The defined? keyword for super for a method taking arguments returns 'super' when a superclass method exists -fails:The defined? keyword for super for a method taking arguments returns 'super' from a block when a superclass method exists -fails:The defined? keyword for super for a method taking arguments returns 'super' from a #define_method when a superclass method exists -fails:The defined? keyword for super for a method taking arguments returns 'super' from a block in a #define_method when a superclass method exists -fails:The defined? keyword for super within an included module's method returns 'super' when a superclass method exists in the including hierarchy -fails:The defined? keyword for instance variables returns nil if not assigned -fails:The defined? keyword for variables when a String does not match a Regexp returns nil for $1-$9 -fails:The defined? keyword for variables when a String matches a Regexp returns nil for non-captures -fails:The defined? keyword for variables when a Regexp does not match a String returns nil for $1-$9 -fails:The defined? keyword for variables when a Regexp matches a String returns nil for non-captures diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/language/encoding_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/encoding_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ -fails:The __ENCODING__ pseudo-variable is an instance of Encoding -fails:The __ENCODING__ pseudo-variable is US-ASCII by default -fails:The __ENCODING__ pseudo-variable is the evaluated strings's one inside an eval -fails:The __ENCODING__ pseudo-variable is the encoding specified by a magic comment inside an eval -fails:The __ENCODING__ pseudo-variable is the encoding specified by a magic comment in the file -fails:The __ENCODING__ pseudo-variable is Encoding::ASCII_8BIT when the interpreter is invoked with -Ka -fails:The __ENCODING__ pseudo-variable is Encoding::ASCII_8BIT when the interpreter is invoked with -KA -fails:The __ENCODING__ pseudo-variable is Encoding::EUC_JP when the interpreter is invoked with -Ke -fails:The __ENCODING__ pseudo-variable is Encoding::EUC_JP when the interpreter is invoked with -KE -fails:The __ENCODING__ pseudo-variable is Encoding::UTF_8 when the interpreter is invoked with -Ku -fails:The __ENCODING__ pseudo-variable is Encoding::UTF_8 when the interpreter is invoked with -KU -fails:The __ENCODING__ pseudo-variable is Encoding::Windows_31J when the interpreter is invoked with -Ks -fails:The __ENCODING__ pseudo-variable is Encoding::Windows_31J when the interpreter is invoked with -KS -fails:The __ENCODING__ pseudo-variable raises a SyntaxError if assigned to diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/language/ensure_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/ensure_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2 +0,0 @@ -fails:An ensure block inside a begin block is executed when an exception is raised in it's corresponding begin block -fails:An ensure block inside a method is executed when an exception is raised in the method diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/language/execution_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/execution_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2 +0,0 @@ -fails:`` returns the output of the executed sub-process -fails:%x is the same as `` diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/language/file_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/file_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,3 +0,0 @@ -fails:The __FILE__ pseudo-variable equals (eval) inside an eval -fails:The __FILE__ pseudo-variable equals the absolute path of a file loaded by an absolute path -fails:The __FILE__ pseudo-variable equals the absolute path of a file loaded by a relative path diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/language/for_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/for_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,6 +0,0 @@ -fails:The for expression iterates over an Hash passing each key-value pair to the block -fails:The for expression allows a class variable as an iterator name -fails:The for expression yields only as many values as there are arguments -fails:The for expression executes code in containing variable scope -fails:The for expression executes code in containing variable scope with 'do' -fails:The for expression returns expr diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/language/hash_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/hash_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -fails:Hash literal freezes string keys on initialization diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/language/line_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/line_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -fails:The __LINE__ pseudo-variable equals the line number of the text in a loaded file diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/language/literal_lambda_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/literal_lambda_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,4 +0,0 @@ -fails:->(){} assigns the given block to the parameter prefixed with an ampersand if such a parameter exists -fails:->(){} sets parameters appropriately when a combination of parameter types is given between the parenthesis -fails:->(){} uses lambda's 'rigid' argument handling -fails:->(){} evaluates constants as normal blocks do diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/language/magic_comment_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/magic_comment_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,8 +0,0 @@ -fails:Magic comment is optional -fails:Magic comment determines __ENCODING__ -fails:Magic comment is case-insensitive -fails:Magic comment must be at the first line -fails:Magic comment must be the first token of the line -fails:Magic comment can be after the shebang -fails:Magic comment can take Emacs style -fails:Magic comment can take vim style diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/language/match_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/match_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2 +0,0 @@ -fails:The !~ operator evaluates as a call to !~ -fails:The =~ operator calls the =~ method diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/language/metaclass_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/metaclass_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,16 +0,0 @@ -fails:self in a metaclass body (class << obj) is TrueClass for true -fails:self in a metaclass body (class << obj) is FalseClass for false -fails:self in a metaclass body (class << obj) is NilClass for nil -fails:self in a metaclass body (class << obj) raises a TypeError for numbers -fails:self in a metaclass body (class << obj) raises a TypeError for symbols -fails:self in a metaclass body (class << obj) is a singleton Class instance -fails:A constant on a metaclass can be accessed via const_get -fails:A constant on a metaclass cannot be accessed via object::CONST -fails:A constant on a metaclass raises a NameError for anonymous_module::CONST -fails:A constant on a metaclass appears in the metaclass constant list -fails:A constant on a metaclass does not appear in the object's class constant list -fails:A constant on a metaclass is not preserved when the object is duped -fails:A constant on a metaclass is preserved when the object is cloned -fails:calling methods on the metaclass calls a method on the instance's metaclass -fails:calling methods on the metaclass calls a method in deeper chains of metaclasses -fails:calling methods on the metaclass calls a method defined on the metaclass of the metaclass diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/language/module_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/module_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,7 +0,0 @@ -fails:The module keyword reopens a module included in Object -fails:The module keyword raises a TypeError if the constant is a Class -fails:The module keyword raises a TypeError if the constant is a String -fails:The module keyword raises a TypeError if the constant is a Fixnum -fails:The module keyword raises a TypeError if the constant is nil -fails:The module keyword raises a TypeError if the constant is true -fails:The module keyword raises a TypeError if the constant is false diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/language/next_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/next_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,9 +0,0 @@ -fails:The next statement from within the block returns the argument passed -fails:The next statement from within the block returns to the invoking method, with the specified value -fails:The next statement from within the block returns to the currently yielding method in case of chained calls -fails:Assignment via next assigns objects -fails:Assignment via next assigns splatted objects -fails:Assignment via next assigns objects to a splatted reference -fails:Assignment via next assigns splatted objects to a splatted reference via a splatted yield -fails:Assignment via next assigns objects to multiple variables -fails:Assignment via next assigns splatted objects to multiple variables diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/language/precedence_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/precedence_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2 +0,0 @@ -fails:Operators + - have higher precedence than >> << -fails:Operators + - are left-associative diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/language/predefined/data_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/predefined/data_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,6 +0,0 @@ -fails:The DATA constant exists when the main script contains __END__ -fails:The DATA constant does not exist when the main script contains no __END__ -fails:The DATA constant does not exist when an included file has a __END__ -fails:The DATA constant does not change when an included files also has a __END__ -fails:The DATA constant is included in an otherwise empty file -fails:The DATA constant succeeds in locking the file DATA came from diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/language/predefined_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/predefined_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,108 +0,0 @@ -fails:Predefined global $~ is set to contain the MatchData object of the last match if successful -fails:Predefined global $~ is set to nil if the last match was unsuccessful -fails:Predefined global $~ is set at the method-scoped level rather than block-scoped -fails:Predefined global $~ raises an error if assigned an object not nil or instanceof MatchData -fails:Predefined global $~ changes the value of derived capture globals when assigned -fails:Predefined global $~ changes the value of the derived preceding match global -fails:Predefined global $~ changes the value of the derived following match global -fails:Predefined global $~ changes the value of the derived full match global -fails:Predefined global $& is equivalent to MatchData#[0] on the last match $~ -fails:Predefined global $& sets the encoding to the encoding of the source String -fails:Predefined global $` is equivalent to MatchData#pre_match on the last match $~ -fails:Predefined global $` sets the encoding to the encoding of the source String -fails:Predefined global $` sets an empty result to the encoding of the source String -fails:Predefined global $' is equivalent to MatchData#post_match on the last match $~ -fails:Predefined global $' sets the encoding to the encoding of the source String -fails:Predefined global $' sets an empty result to the encoding of the source String -fails:Predefined global $+ is equivalent to $~.captures.last -fails:Predefined global $+ captures the last non nil capture -fails:Predefined global $+ sets the encoding to the encoding of the source String -fails:Predefined globals $1..N are equivalent to $~[N] -fails:Predefined globals $1..N are nil unless a match group occurs -fails:Predefined globals $1..N sets the encoding to the encoding of the source String -fails:Predefined global $stdout is the same as $DEFAULT_OUTPUT from 'English' library -fails:Predefined global $stdout raises TypeError error if assigned to nil -fails:Predefined global $stdout raises TypeError error if assigned to object that doesn't respond to #write -fails:Predefined global $! remains nil after a failed core class "checked" coercion against a class that defines method_missing -fails:Predefined global $/ changes $-0 -fails:Predefined global $/ does not call #to_str to convert the object to a String -fails:Predefined global $/ raises a TypeError if assigned a Fixnum -fails:Predefined global $/ raises a TypeError if assigned a boolean -fails:Predefined global $-0 changes $/ -fails:Predefined global $-0 does not call #to_str to convert the object to a String -fails:Predefined global $-0 raises a TypeError if assigned a Fixnum -fails:Predefined global $-0 raises a TypeError if assigned a boolean -fails:Predefined global $, raises TypeError if assigned a non-String -fails:Predefined global $_ is set to the last line read by e.g. StringIO#gets -fails:Predefined global $_ is set at the method-scoped level rather than block-scoped -fails:Predefined global $_ is Thread-local -fails:Execution variable $: does not include '.' when the taint check level > 1 -fails:Execution variable $: is the same object as $LOAD_PATH and $-I -fails:Execution variable $: is read-only -fails:Global variable $" is read-only -fails:Global variable $< is read-only -fails:Global variable $FILENAME is read-only -fails:Global variable $? is read-only -fails:Global variable $? is thread-local -fails:Global variable $-a is read-only -fails:Global variable $-l is read-only -fails:Global variable $-p is read-only -fails:Global variable $-d is an alias of $DEBUG -fails:Global variable $-v is an alias of $VERBOSE -fails:Global variable $-w is an alias of $VERBOSE -fails:Global variable $0 raises a TypeError when not given an object that can be coerced to a String -fails:The predefined standard objects includes ARGF -fails:The predefined global constants includes TRUE -fails:The predefined global constants includes FALSE -fails:The predefined global constants includes NIL -fails:The predefined global constants includes STDIN -fails:The predefined global constants includes STDOUT -fails:The predefined global constants includes STDERR -fails:The predefined global constants includes RUBY_RELEASE_DATE -fails:The predefined global constants includes TOPLEVEL_BINDING -fails:Processing RUBYOPT adds the -I path to $LOAD_PATH -fails:Processing RUBYOPT sets $DEBUG to true for '-d' -fails:Processing RUBYOPT prints the version number for '-v' -fails:Processing RUBYOPT sets $VERBOSE to true for '-w' -fails:Processing RUBYOPT sets $VERBOSE to true for '-W' -fails:Processing RUBYOPT sets $VERBOSE to nil for '-W0' -fails:Processing RUBYOPT sets $VERBOSE to false for '-W1' -fails:Processing RUBYOPT sets $VERBOSE to true for '-W2' -fails:Processing RUBYOPT requires the file for '-r' -fails:Processing RUBYOPT raises a RuntimeError for '-a' -fails:Processing RUBYOPT raises a RuntimeError for '-p' -fails:Processing RUBYOPT raises a RuntimeError for '-n' -fails:Processing RUBYOPT raises a RuntimeError for '-y' -fails:Processing RUBYOPT raises a RuntimeError for '-c' -fails:Processing RUBYOPT raises a RuntimeError for '-s' -fails:Processing RUBYOPT raises a RuntimeError for '-h' -fails:Processing RUBYOPT raises a RuntimeError for '--help' -fails:Processing RUBYOPT raises a RuntimeError for '-l' -fails:Processing RUBYOPT raises a RuntimeError for '-S' -fails:Processing RUBYOPT raises a RuntimeError for '-e' -fails:Processing RUBYOPT raises a RuntimeError for '-i' -fails:Processing RUBYOPT raises a RuntimeError for '-x' -fails:Processing RUBYOPT raises a RuntimeError for '-C' -fails:Processing RUBYOPT raises a RuntimeError for '-X' -fails:Processing RUBYOPT raises a RuntimeError for '-F' -fails:Processing RUBYOPT raises a RuntimeError for '-0' -fails:Processing RUBYOPT raises a RuntimeError for '--copyright' -fails:Processing RUBYOPT raises a RuntimeError for '--version' -fails:Processing RUBYOPT raises a RuntimeError for '--yydebug' -fails:The predefined global constant STDERR has nil for the external encoding despite Encoding.default_external being changed -fails:The predefined global constant STDERR has the encodings set by #set_encoding -fails:The predefined global constant ARGV contains Strings encoded in locale Encoding -fails:The predefined global constant STDERR has nil for the internal encoding despite Encoding.default_internal being changed -fails:The predefined global constant STDERR has nil for the internal encoding -fails:The predefined global constant STDERR has nil for the external encoding -fails:The predefined global constant STDOUT has nil for the internal encoding despite Encoding.default_internal being changed -fails:The predefined global constant STDOUT has nil for the internal encoding -fails:The predefined global constant STDOUT has the encodings set by #set_encoding -fails:The predefined global constant STDOUT has nil for the external encoding despite Encoding.default_external being changed -fails:The predefined global constant STDOUT has nil for the external encoding -fails:The predefined global constant STDIN has nil for the internal encoding despite Encoding.default_internal being changed -fails:The predefined global constant STDIN has nil for the internal encoding -fails:The predefined global constant STDIN retains the encoding set by #set_encoding when Encoding.default_external is changed -fails:The predefined global constant STDIN has the encodings set by #set_encoding -fails:The predefined global constant STDIN has the same external encoding as Encoding.default_external when that encoding is changed -fails:The predefined global constant STDIN has the same external encoding as Encoding.default_external diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/language/private_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/private_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -fails:The private keyword is overridden when a new class is opened diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/language/proc_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/proc_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,18 +0,0 @@ -fails:A Proc taking zero arguments raises an ArgumentErro if a value is passed -fails:A Proc taking || arguments raises an ArgumentError if a value is passed -fails:A Proc taking |a| arguments does not call #to_ary to convert a single passed object to an Array -fails:A Proc taking |a| arguments raises an ArgumentError if no value is passed -fails:A Proc taking |a, b| arguments raises an ArgumentError if passed no values -fails:A Proc taking |a, b| arguments raises an ArgumentError if passed one value -fails:A Proc taking |a, b| arguments does not call #to_ary to convert a single passed object to an Array -fails:A Proc taking |a, *b| arguments raises an ArgumentError if passed no values -fails:A Proc taking |a, *b| arguments does not call #to_ary to convert a single passed object to an Array -fails:A Proc taking |*| arguments does not call #to_ary to convert a single passed object to an Array -fails:A Proc taking |*a| arguments does not call #to_ary to convert a single passed object to an Array -fails:A Proc taking |a, | arguments raises an ArgumentError when passed no values -fails:A Proc taking |a, | arguments raises an ArgumentError when passed more than one value -fails:A Proc taking |a, | arguments does not call #to_ary to convert a single passed object to an Array -fails:A Proc taking |(a, b)| arguments raises an ArgumentError when passed no values -fails:A Proc taking |(a, b)| arguments calls #to_ary to convert a single passed object to an Array -fails:A Proc taking |(a, b)| arguments raises an TypeError if #to_ary does not return an Array -fails:A Proc taking |(a, b)| arguments destructures a single Array value yielded diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/language/redo_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/redo_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,3 +0,0 @@ -fails:The redo statement restarts block execution if used within block -fails:The redo statement re-executes the closest loop -fails:The redo statement re-executes the last step in enumeration diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/language/regexp/anchors_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/regexp/anchors_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -fails:Regexps with anchors supports B (non-word-boundary) diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/language/regexp/back-references_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/regexp/back-references_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,4 +0,0 @@ -fails:Regexps with back-references saves match data in the $~ pseudo-global variable -fails:Regexps with back-references saves captures in numbered $[1-9] variables -fails:Regexps with back-references will not clobber capture variables across threads -fails:Regexps with back-references resets nested backreference before match of outer subexpression diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/language/regexp/character_classes_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/regexp/character_classes_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,68 +0,0 @@ -fails:Regexp with character classes supports [] (character class) -fails:Regexp with character classes supports [[:alpha:][:digit:][:etc:]] (predefined character classes) -fails:Regexp with character classes matches ASCII characters with [[:ascii:]] -fails:Regexp with character classes matches Unicode letter characters with [[:alnum:]] -fails:Regexp with character classes matches Unicode digits with [[:alnum:]] -fails:Regexp with character classes doesn't match Unicode control characters with [[:alnum:]] -fails:Regexp with character classes doesn't match Unicode punctuation characters with [[:alnum:]] -fails:Regexp with character classes matches Unicode letter characters with [[:alpha:]] -fails:Regexp with character classes doesn't match Unicode digits with [[:alpha:]] -fails:Regexp with character classes doesn't match Unicode control characters with [[:alpha:]] -fails:Regexp with character classes doesn't match Unicode punctuation characters with [[:alpha:]] -fails:Regexp with character classes matches Unicode space characters with [[:blank:]] -fails:Regexp with character classes matches Unicode control characters with [[:cntrl:]] -fails:Regexp with character classes matches Unicode digits with [[:digit:]] -fails:Regexp with character classes matches Unicode letter characters with [[:graph:]] -fails:Regexp with character classes matches Unicode digits with [[:graph:]] -fails:Regexp with character classes matches Unicode marks with [[:graph:]] -fails:Regexp with character classes matches Unicode punctuation characters with [[:graph:]] -fails:Regexp with character classes match Unicode format characters with [[:graph:]] -fails:Regexp with character classes match Unicode private-use characters with [[:graph:]] -fails:Regexp with character classes matches Unicode lowercase letter characters with [[:lower:]] -fails:Regexp with character classes matches Unicode lowercase letter characters with [[:print:]] -fails:Regexp with character classes matches Unicode uppercase letter characters with [[:print:]] -fails:Regexp with character classes matches Unicode title-case characters with [[:print:]] -fails:Regexp with character classes matches Unicode digits with [[:print:]] -fails:Regexp with character classes matches Unicode marks with [[:print:]] -fails:Regexp with character classes matches Unicode punctuation characters with [[:print:]] -fails:Regexp with character classes match Unicode format characters with [[:print:]] -fails:Regexp with character classes match Unicode private-use characters with [[:print:]] -fails:Regexp with character classes matches Unicode Pc characters with [[:punct:]] -fails:Regexp with character classes matches Unicode Pd characters with [[:punct:]] -fails:Regexp with character classes matches Unicode Ps characters with [[:punct:]] -fails:Regexp with character classes matches Unicode Pe characters with [[:punct:]] -fails:Regexp with character classes matches Unicode Pi characters with [[:punct:]] -fails:Regexp with character classes matches Unicode Pf characters with [[:punct:]] -fails:Regexp with character classes matches Unicode Pf characters with [[:punct:]] -fails:Regexp with character classes matches Unicode Po characters with [[:punct:]] -fails:Regexp with character classes matches Unicode Zs characters with [[:space:]] -fails:Regexp with character classes matches Unicode Zl characters with [[:space:]] -fails:Regexp with character classes matches Unicode Zp characters with [[:space:]] -fails:Regexp with character classes matches Unicode uppercase characters with [[:upper:]] -fails:Regexp with character classes doesn't match Unicode letter characters [^a-fA-F] with [[:xdigit:]] -fails:Regexp with character classes matches Unicode letter characters [a-fA-F] with [[:xdigit:]] -fails:Regexp with character classes matches Unicode lowercase characters with [[:word:]] -fails:Regexp with character classes matches Unicode uppercase characters with [[:word:]] -fails:Regexp with character classes matches Unicode title-case characters with [[:word:]] -fails:Regexp with character classes matches Unicode decimal digits with [[:word:]] -fails:Regexp with character classes matches Unicode marks with [[:word:]] -fails:Regexp with character classes match Unicode Nl characters with [[:word:]] -fails:Regexps with anchors supports ^ (line start anchor) -fails:Regexp with character classes doesn't matches Unicode marks with [[:alnum:]] -fails:Regexp with character classes doesn't match Unicode lowercase letter characters with [[:punct:]] -fails:Regexp with character classes doesn't match Unicode uppercase letter characters with [[:punct:]] -fails:Regexp with character classes doesn't match Unicode title-case characters with [[:punct:]] -fails:Regexp with character classes doesn't match Unicode digits with [[:punct:]] -fails:Regexp with character classes doesn't match Unicode marks with [[:punct:]] -fails:Regexp with character classes doesn't match Unicode format characters with [[:punct:]] -fails:Regexp with character classes doesn't match Unicode private-use characters with [[:punct:]] -fails:Regexp with character classes doesn't match Unicode lowercase characters with [[:upper:]] -fails:Regexp with character classes doesn't match Unicode title-case characters with [[:upper:]] -fails:Regexp with character classes doesn't match Unicode digits with [[:upper:]] -fails:Regexp with character classes doesn't match Unicode marks with [[:upper:]] -fails:Regexp with character classes doesn't match Unicode punctuation characters with [[:upper:]] -fails:Regexp with character classes doesn't match Unicode control characters with [[:upper:]] -fails:Regexp with character classes doesn't match Unicode format characters with [[:upper:]] -fails:Regexp with character classes doesn't match Unicode private-use characters with [[:upper:]] -fails:Regexps with escape characters support \x (hex characters) -fails:Regexps with escape characters support \c (control characters) diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/language/regexp/encoding_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/regexp/encoding_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,23 +0,0 @@ -fails:Regexps with encoding modifiers supports /e (EUC encoding) -fails:Regexps with encoding modifiers supports /e (EUC encoding) with interpolation -fails:Regexps with encoding modifiers supports /e (EUC encoding) with interpolation /o -fails:Regexps with encoding modifiers uses EUC-JP as /e encoding -fails:Regexps with encoding modifiers preserves EUC-JP as /e encoding through interpolation -fails:Regexps with encoding modifiers supports /n (No encoding) -fails:Regexps with encoding modifiers supports /n (No encoding) with interpolation -fails:Regexps with encoding modifiers supports /n (No encoding) with interpolation /o -fails:Regexps with encoding modifiers uses US-ASCII as /n encoding if all chars are 7-bit -fails:Regexps with encoding modifiers uses ASCII-8BIT as /n encoding if not all chars are 7-bit -fails:Regexps with encoding modifiers preserves US-ASCII as /n encoding through interpolation if all chars are 7-bit -fails:Regexps with encoding modifiers preserves ASCII-8BIT as /n encoding through interpolation if all chars are 7-bit -fails:Regexps with encoding modifiers supports /s (Windows_31J encoding) -fails:Regexps with encoding modifiers supports /s (Windows_31J encoding) with interpolation -fails:Regexps with encoding modifiers supports /s (Windows_31J encoding) with interpolation and /o -fails:Regexps with encoding modifiers uses Windows-31J as /s encoding -fails:Regexps with encoding modifiers preserves Windows-31J as /s encoding through interpolation -fails:Regexps with encoding modifiers supports /u (UTF8 encoding) -fails:Regexps with encoding modifiers supports /u (UTF8 encoding) with interpolation -fails:Regexps with encoding modifiers supports /u (UTF8 encoding) with interpolation and /o -fails:Regexps with encoding modifiers uses UTF-8 as /u encoding -fails:Regexps with encoding modifiers preserves UTF-8 as /u encoding through interpolation -fails:Regexps with encoding modifiers selects last of multiple encoding specifiers diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/language/regexp/escapes_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/regexp/escapes_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2 +0,0 @@ -fails:Regexps with escape characters support \x (hex characters) -fails:Regexps with escape characters support \c (control characters) diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/language/regexp/grouping_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/regexp/grouping_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -fails:Regexps with grouping raise a SyntaxError when parentheses aren't balanced diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/language/regexp/interpolation_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/regexp/interpolation_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,7 +0,0 @@ -fails:Regexps with interpolation allows interpolation of literal regexps -fails:Regexps with interpolation allows interpolation of any class that responds to to_s -fails:Regexps with interpolation allows interpolation which mixes modifiers -fails:Regexps with interpolation gives precedence to escape sequences over substitution -fails:Regexps with interpolation throws RegexpError for malformed interpolation -fails:Regexps with interpolation allows interpolation in extended mode -fails:Regexps with interpolation allows escape sequences in interpolated regexps diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/language/regexp/modifiers_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/regexp/modifiers_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,9 +0,0 @@ -fails:Regexps with modifers supports /m (multiline) -fails:Regexps with modifers supports /x (extended syntax) -fails:Regexps with modifers supports /o (once) -fails:Regexps with modifers invokes substitutions for /o only once -fails:Regexps with modifers supports (?imx-imx) (inline modifiers) -fails:Regexps with modifers supports (?imx-imx:expr) (scoped inline modifiers) -fails:Regexps with modifers supports . with /m -fails:Regexps with modifers supports ASII/Unicode modifiers -fails:Regexps with modifers raises SyntaxError for ASII/Unicode modifiers diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/language/regexp/repetition_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/regexp/repetition_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -fails:Regexps with repetition does not treat {m,n}+ as possessive diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/specs/tags/language/regexp_tags.txt --- a/graal/com.oracle.truffle.ruby.test/specs/tags/language/regexp_tags.txt Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,16 +0,0 @@ -fails:Literal Regexps matches against $_ (last input) in a conditional if no explicit matchee provided -fails:Literal Regexps throws SyntaxError for malformed literals -fails:Literal Regexps supports paired delimiters with %r -fails:Literal Regexps supports grouping constructs that are also paired delimiters -fails:Literal Regexps allows second part of paired delimiters to be used as non-paired delimiters -fails:Literal Regexps supports non-paired delimiters delimiters with %r -fails:Literal Regexps allows unescaped / to be used with %r -fails:Literal Regexps supports . (any character except line terminator) -fails:Literal Regexps supports | (alternations) -fails:Literal Regexps supports (?> ) (embedded subexpression) -fails:Literal Regexps supports (?# ) -fails:Literal Regexps supports (?<= ) (positive lookbehind) -fails:Literal Regexps supports (? 2 }; puts bar.to_s"); - } - - @Test - public void testInclude() { - assertPrints("true\nfalse\n", "foo = [1, 2, 3, 4]; puts foo.include? 2; puts foo.include? 5"); - } - - @Test - public void testSub() { - assertPrints("[1, 4]\n", "puts ([1, 2, 2, 3, 4] - [2, 3]).to_s"); - } - - @Test - public void testJoin() { - assertPrints("1.2.3\n", "puts [1, 2, 3].join('.')"); - } - - @Test - public void testShift() { - assertPrints("1\n2\n3\n", "a = [1, 2, 3]; while b = a.shift; puts b; end"); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/BignumTests.java --- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/BignumTests.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.test.core; - -import org.junit.*; - -import com.oracle.truffle.ruby.test.*; - -/** - * Test the {@code Bignum} class. - */ -public class BignumTests extends RubyTests { - - @Test - public void testImmediate() { - assertPrints("123456789123456789\n", "puts 123456789123456789"); - assertPrints("574658776654483828\n", "puts 574658776654483828"); - } - - @Test - public void testAddImmediate() { - assertPrints("821572354901397406\n", "puts 123456789123456789+698115565777940617"); - assertPrints("7675735362615108\n", "puts 867676857675 + 7674867685757433"); - assertPrints("8792416214481\n", "puts 8785647643454 + (6768571027)"); - assertPrints("8089240320234\n", "puts (7132953783486) + ((956286536748))"); - } - - @Test - public void testSubImmediate() { - assertPrints("574658776654483828\n", "puts 698115565777940617-123456789123456789"); - assertPrints("7674000008899758\n", "puts 7674867685757433 - 867676857675"); - assertPrints("8778879072427\n", "puts 8785647643454 - (6768571027)"); - assertPrints("6176667246738\n", "puts (7132953783486) - ((956286536748))"); - } - - @Test - public void testLessImmediate() { - assertPrints("false\n", "puts 698115565777940617 < 123456789123456789"); - assertPrints("true\n", "puts 867676857675 < 7674867685757433"); - assertPrints("false\n", "puts 8785647643454 < (6768571027)"); - assertPrints("true\n", "puts (956286536748) < ((7132953783486))"); - } - - @Test - public void testDivmod() { - assertPrints("100\n2342\n", "puts 1000000000000000000000002342.divmod(10000000000000000000000000)"); - assertPrints("Fixnum\n", "puts 1000000000000000000000002342.divmod(10000000000000000000000000)[0].class"); - assertPrints("Fixnum\n", "puts 1000000000000000000000002342.divmod(10000000000000000000000000)[1].class"); - } -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/BoolTests.java --- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/BoolTests.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.test.core; - -import org.junit.*; - -import com.oracle.truffle.ruby.test.*; - -/** - * Test {@code true} and {@code false}. Note that there is no {@code Bool} class or type. There is - * {@code TrueClass}, {@code FalseClass}, and instances of them {@code true} and {@code false}. - */ -public class BoolTests extends RubyTests { - - @Test - public void testImmediate() { - assertPrints("true\n", "puts true"); - assertPrints("false\n", "puts false"); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/ContinuationTests.java --- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/ContinuationTests.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.test.core; - -import org.junit.*; - -import com.oracle.truffle.ruby.test.*; - -/** - * Test the {@code Continuation} class. - */ -public class ContinuationTests extends RubyTests { - - @Test - public void testRequired() { - assertPrints("", "callcc { |c| c.call }"); - } - - @Test - public void testOneShotGoingUpCallstack() { - assertPrints("1\n3\n", "callcc { |c| puts 1; c.call; puts 2 }; puts 3"); - } - - @Test - public void testOneShotGoingUpCallstackReturnValue() { - assertPrints("14\n", "puts callcc { |c| c.call 14 }"); - } - - @Test - public void testNestedOneShotGoingUpCallstack() { - assertPrints("1\n2\n4\n5\n", "callcc { |c1| puts 1; callcc { |c2| puts 2; c2.call; puts 3 }; puts 4 }; puts 5"); - assertPrints("1\n2\n5\n", "callcc { |c1| puts 1; callcc { |c2| puts 2; c1.call; puts 3 }; puts 4 }; puts 5"); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/FiberTests.java --- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/FiberTests.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.test.core; - -import org.junit.*; - -import com.oracle.truffle.ruby.test.*; - -/** - * Test the {@code Fiber} class. - */ -public class FiberTests extends RubyTests { - - @Test - public void testResume() { - assertPrints("14\n", "f = Fiber.new { |x| puts x }; f.resume 14"); - } - - @Test - public void testYield() { - assertPrints("14\n", "f = Fiber.new { |x| Fiber.yield x }; puts f.resume(14)"); - } - - @Test - public void testCountdown() { - assertPrints("", "f = Fiber.new do |n|\n" + // - " loop do\n" + // - " n = Fiber.yield n - 1\n" + // - " end\n" + // - "end\n" + // - "\n" + // - "n = 1000\n" + // - "\n" + // - "while n > 0\n" + // - " n = f.resume n\n" + // - "end\n"); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/FixnumTests.java --- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/FixnumTests.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,134 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.test.core; - -import org.junit.*; - -import com.oracle.truffle.ruby.test.*; - -/** - * Test the {@code Fixnum} class. - */ -public class FixnumTests extends RubyTests { - - @Test - public void testImmediate() { - assertPrints("2\n", "puts 2"); - assertPrints("14\n", "puts 14"); - assertPrints("-14\n", "puts -14"); - } - - @Test - public void testNegate() { - assertPrints("-1\n", "x = 1; puts -x"); - assertPrints("1\n", "x = -1; puts -x"); - } - - @Test - public void testAddImmediate() { - assertPrints("16\n", "puts 14+2"); - assertPrints("14\n", "puts 12 + 2"); - assertPrints("17\n", "puts 9 + (8)"); - assertPrints("10\n", "puts (6) + ((4))"); - } - - @Test - public void testSubImmediate() { - assertPrints("12\n", "puts 14-2"); - assertPrints("10\n", "puts 12 - 2"); - assertPrints("1\n", "puts 9 - (8)"); - assertPrints("2\n", "puts (6) - ((4))"); - } - - @Test - public void testMulImmediate() { - assertPrints("28\n", "puts 14 * 2"); - assertPrints("20\n", "puts 2 * 10"); - assertPrints("72\n", "puts 9 * (8)"); - assertPrints("24\n", "puts (4) * ((6))"); - } - - @Test - public void testDivImmediate() { - assertPrints("7\n", "puts 14 / 2"); - assertPrints("0\n", "puts 2 / 10"); - assertPrints("1\n", "puts 9 / (8)"); - assertPrints("0\n", "puts (4) / ((6))"); - } - - @Test - public void testEqualImmediate() { - assertPrints("true\n", "puts 14 == 14"); - assertPrints("true\n", "puts 2 == 2"); - assertPrints("false\n", "puts 9 == (8)"); - assertPrints("false\n", "puts (4) == ((6))"); - } - - @Test - public void testNotEqualImmediate() { - assertPrints("false\n", "puts 14 != 14"); - assertPrints("false\n", "puts 2 != 2"); - assertPrints("true\n", "puts 9 != (8)"); - assertPrints("true\n", "puts (4) != ((6))"); - } - - @Test - public void testLessImmediate() { - assertPrints("false\n", "puts 14 < 2"); - assertPrints("true\n", "puts 2 < 10"); - assertPrints("false\n", "puts 9 < (8)"); - assertPrints("true\n", "puts (4) < ((6))"); - } - - @Test - public void testGreaterEqualImmediate() { - assertPrints("true\n", "puts 14 >= 14"); - assertPrints("true\n", "puts 14 >= 2"); - assertPrints("false\n", "puts 2 >= 10"); - assertPrints("true\n", "puts 9 >= (8)"); - assertPrints("false\n", "puts (4) >= ((6))"); - } - - @Test - public void testLeftShift() { - assertPrints("0\n", "puts 0 << 0"); - assertPrints("0\n", "puts 0 << 1"); - assertPrints("1\n", "puts 1 << 0"); - assertPrints("0\n", "puts 1 << -1"); - assertPrints("0\n", "puts 1 << -2"); - assertPrints("28\n", "puts 14 << 1"); - assertPrints("7\n", "puts 14 << -1"); - assertPrints("4294967296\n", "puts 1 << 32"); - assertPrints("340282366920938463463374607431768211456\n", "puts 1 << 128"); - assertPrints("0\n", "puts 1 << -32"); - assertPrints("Fixnum\n", "puts (14 << 1).class"); - assertPrints("Bignum\n", "puts (1 << 32).class"); - } - - @Test - public void testDivmod() { - // @formatter:off - final int[][] tests = new int[][]{ - new int[]{13, 4, 3, 1}, - new int[]{13, -4, -4, -3}, - new int[]{-13, 4, -4, 3}, - new int[]{-13, -4, 3, -1}}; - // @formatter:on - - for (int[] test : tests) { - final int a = test[0]; - final int b = test[1]; - final int q = test[2]; - final int r = test[3]; - assertPrints(String.format("%d\n%d\n", q, r), String.format("puts %d.divmod(%d)", a, b)); - } - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/FloatTests.java --- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/FloatTests.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.test.core; - -import org.junit.*; - -import com.oracle.truffle.ruby.test.*; - -/** - * Test the {@code Float} class. - */ -public class FloatTests extends RubyTests { - - @Test - public void testImmediate() { - assertPrints("2.5\n", "puts 2.5"); - assertPrints("14.33\n", "puts 14.33"); - } - - @Test - public void testAddImmediate() { - assertPrints("16.2\n", "puts 14.1+2.1"); - assertPrints("14.2\n", "puts 12.1 + 2.1"); - assertPrints("17.2\n", "puts 9.1 + (8.1)"); - assertPrints("10.2\n", "puts (6.1) + ((4.1))"); - } - - @Test - public void testSubImmediate() { - assertPrints("12.1\n", "puts 14.2-2.1"); - assertPrints("10.1\n", "puts 12.2 - 2.1"); - assertPrints("1.0999999999999996\n", "puts 9.2 - (8.1)"); - assertPrints("2.1000000000000005\n", "puts (6.2) - ((4.1))"); - } - - @Test - public void testMulImmediate() { - assertPrints("29.82\n", "puts 14.2*2.1"); - assertPrints("25.62\n", "puts 12.2 * 2.1"); - assertPrints("74.52\n", "puts 9.2 * (8.1)"); - assertPrints("25.419999999999998\n", "puts (6.2) * ((4.1))"); - assertPrints("7.5\n", "puts 2.5 * 3"); - assertPrints("7.5\n", "puts 3 * 2.5"); - } - - @Test - public void testDivImmediate() { - assertPrints("6.761904761904761\n", "puts 14.2/2.1"); - assertPrints("5.809523809523809\n", "puts 12.2 / 2.1"); - assertPrints("1.1358024691358024\n", "puts 9.2 / (8.1)"); - assertPrints("1.5121951219512197\n", "puts (6.2) / ((4.1))"); - assertPrints("0.8333333333333334\n", "puts 2.5 / 3"); - assertPrints("1.2\n", "puts 3 / 2.5"); - } - - @Test - public void testLessImmediate() { - assertPrints("false\n", "puts 14.2<2.2"); - assertPrints("true\n", "puts 2.2 < 10.2"); - assertPrints("false\n", "puts 9.2 < (8.2)"); - assertPrints("true\n", "puts (4.2) < ((6.2))"); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/HashTests.java --- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/HashTests.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.test.core; - -import org.junit.*; - -import com.oracle.truffle.ruby.test.*; - -/** - * Test the {@code Hash} class. - */ -public class HashTests extends RubyTests { - - @Test - public void testLiteral() { - assertPrints("Hash\n", "puts ({}).class"); - assertPrints("Hash\n", "puts ({1 => 2, 3 => 4}).class"); - assertPrints("Hash\n", "puts ({key1: 2, key3: 4}).class"); - } - - @Test - public void testIndex() { - assertPrints("4\n", "foo = {1 => 2, 3 => 4}; puts foo[3]"); - } - - @Test - public void testIndexSet() { - assertPrints("6\n", "foo = {1 => 2, 3 => 4}; foo[5] = 6; puts foo[5]"); - } - - @Test - public void testKeys() { - assertPrints("[1, 3]\n", "foo = {1 => 2, 3 => 4}; puts foo.keys.to_s"); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/IntegerTests.java --- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/IntegerTests.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.test.core; - -import org.junit.*; - -import com.oracle.truffle.ruby.test.*; - -/** - * Test the {@code Integer} class. - */ -public class IntegerTests extends RubyTests { - - @Test - public void testTimes() { - assertPrints("0\n", "1.times { |i| puts i }"); - assertPrints("0\n1\n2\n", "3.times { |i| puts i }"); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/KernelTests.java --- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/KernelTests.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,111 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.test.core; - -import org.junit.*; - -import com.oracle.truffle.ruby.runtime.configuration.*; -import com.oracle.truffle.ruby.test.*; - -/** - * Test {@code Kernel}. - */ -public class KernelTests extends RubyTests { - - @Test - public void testPutsEmpty() { - assertPrints("\n", "puts"); - } - - @Test - public void testPutsString() { - assertPrints("1\n", "puts 1"); - } - - @Test - public void testPrintfNoFormatting() { - assertPrints("", "printf"); - assertPrints("foo", "printf \"foo\""); - assertPrints("foo\n", "printf \"foo\\n\""); - } - - @Test - public void testPrintfDecimal() { - assertPrints("foo14bar", "printf \"foo%dbar\", 14"); - } - - @Test - public void testGets() { - assertPrintsWithInput("test\n", "puts gets", "test\n"); - } - - @Test - public void testInteger() { - assertPrints("14\n", "puts Integer(\"14\")"); - } - - @Test - public void testEval() { - assertPrints("16\n", "puts eval(\"14 + 2\")"); - } - - @Test - public void testBindingLocalVariables() { - // Use the current binding for eval - assertPrints("16\n", "x = 14; y = 2; puts eval(\"x + y\", binding)"); - - // Use the binding returned from a method for eval - assertPrints("16\n", "def foo; x = 14; y = 2; binding; end; puts eval(\"x + y\", foo)"); - } - - @Test - public void testBindingInstanceVariables() { - // Use the binding returned from a method in an object for eval - assertPrints("16\n", "class Foo; def foo; @x = 14; @y = 2; binding; end; end; puts eval(\"@x + @y\", Foo.new.foo)"); - } - - @Ignore - @Test - public void testSetTraceFuncLine() { - final ConfigurationBuilder configuration = new ConfigurationBuilder(); - configuration.setTrace(true); - - final String code = "def foo\n" + // - " a = 14\n" + // - " b = 2\n" + // - " a + b\n" + // - "end\n" + // - "\n" + // - "set_trace_func proc { |event, file, line, id, binding, classname|\n" + // - " if event == \"line\"\n" + // - " puts file + \":\" + line.to_s\n" + // - " end\n" + // - "}\n" + // - "\n" + // - "foo"; - final String input = ""; - final String expected = "(test):13\n(test):2\n(test):3\n(test):4\n"; - assertPrints(new Configuration(configuration), expected, "(test)", code, input); - } - - @Test - public void testBlockGiven() { - assertPrints("false\n", "def foo; puts block_given?; end; foo"); - assertPrints("true\n", "def foo; puts block_given?; end; foo do; end"); - assertPrints("true\n", "def foo; puts block_given?; end; foo {}"); - assertPrints("true\n", "def foo; puts block_given?; end; foo &:+"); - } - - @Test - public void testLoop() { - assertPrints("14\n", "loop do; break; end; puts 14"); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/MathTests.java --- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/MathTests.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.test.core; - -import org.junit.*; - -import com.oracle.truffle.ruby.test.*; - -/** - * Test the {@code Math} class. - */ -public class MathTests extends RubyTests { - - @Test - public void testPI() { - assertPrints("3.141592653589793\n", "puts Math::PI"); - } - - @Test - public void testSqrt() { - assertPrints("1.0\n", "puts Math.sqrt(1)"); - assertPrints("1.0\n", "puts Math::sqrt(1)"); - assertPrints("3.7416573867739413\n", "puts Math::sqrt(14)"); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/ModuleTests.java --- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/ModuleTests.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.test.core; - -import org.junit.*; - -import com.oracle.truffle.ruby.test.*; - -/** - * Test the {@code Module} class. - */ -public class ModuleTests extends RubyTests { - - @Test - public void testAttrAccessor() { - assertPrints("14\n", "class Foo; attr_accessor :x end; foo=Foo.new; foo.x=14; puts foo.x"); - assertPrints("14\n", "class Foo; attr_accessor(:x) end; foo=Foo.new; foo.x=14; puts foo.x"); - assertPrints("16\n", "class Foo; attr_accessor(:x, :y) end; foo=Foo.new; foo.x=14; foo.y=2; puts foo.x + foo.y"); - assertPrints("16\n", "class Foo; attr_accessor :x end; foo=Foo.new; foo.x=2; foo.x+=14; puts foo.x"); - } - - @Test - public void testDefineMethod() { - /* - * We use Object#send instead of calling define_method directly because that method is - * private. - */ - - assertPrints("14\n", "class Foo; end; Foo.send(:define_method, :foo) do; puts 14; end; Foo.new.foo"); - } - - @Test - public void testDefinedBeforeScopeRun() { - assertPrints("Module\n", "module Foo; puts Foo.class; end"); - } - - @Test - public void testDefinedInRootScopeBeforeScopeRun() { - assertPrints("Module\n", "module Foo; puts ::Foo.class; end"); - } - - @Test - public void testModuleEval() { - assertPrints("14\n", "class Foo; puts 14; end; Foo.module_eval('def foo; end'); Foo.new.foo"); - } - - @Test - public void testNextInBlock() { - assertPrints("1\n1\n1\n", "3.times do; puts 1; next; puts 2; end"); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/ObjectSpaceTests.java --- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/ObjectSpaceTests.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.test.core; - -import org.junit.*; - -import com.oracle.truffle.ruby.runtime.configuration.*; -import com.oracle.truffle.ruby.test.*; - -/** - * Test the {@code ObjectSpace} module. - */ -public class ObjectSpaceTests extends RubyTests { - - @Test - public void testEachObjectClass() { - assertPrints("true\n", "found_string = false; ObjectSpace.each_object(Class) { |o| if o == String; found_string = true; end }; puts found_string"); - } - - @Test - public void testId2RefClass() { - assertPrints("true\n", "puts ObjectSpace._id2ref(String.object_id) == String"); - } - - @Test - public void testEachObjectString() { - final ConfigurationBuilder configurationBuilder = new ConfigurationBuilder(); - configurationBuilder.setFullObjectSpace(true); - final String code = "foo = \"foo\"; found_foo = false; ObjectSpace.each_object(String) { |o| if o == foo; found_foo= true; end }; puts found_foo"; - final String input = ""; - final String expected = "true\n"; - assertPrints(new Configuration(configurationBuilder), expected, "(test)", code, input); - } - - @Test - public void testId2RefString() { - final ConfigurationBuilder configurationBuilder = new ConfigurationBuilder(); - configurationBuilder.setFullObjectSpace(true); - final String code = "foo = \"foo\"; puts ObjectSpace._id2ref(foo.object_id) == foo"; - final String input = ""; - final String expected = "true\n"; - assertPrints(new Configuration(configurationBuilder), expected, "(test)", code, input); - } - - @Test - public void testGarbageCollect() { - assertPrints("", "ObjectSpace.garbage_collect"); - assertPrints("", "ObjectSpace.start"); - } -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/ObjectTests.java --- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/ObjectTests.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.test.core; - -import org.junit.*; - -import com.oracle.truffle.ruby.test.*; - -/** - * Test the {@code Object} class. - */ -public class ObjectTests extends RubyTests { - - @Test - public void testARGV() { - assertPrints("1\n2\n3\n", "puts ARGV", "1", "2", "3"); - } - - @Test - public void testInstanceVariableDefined() { - assertPrints("true\n", "class Foo; def initialize; @bar=14; end; end; puts Foo.new.instance_variable_defined?(:@bar)"); - assertPrints("true\n", "class Foo; def initialize; @bar=14; end; end; puts Foo.new.instance_variable_defined?(\"@bar\")"); - assertPrints("true\n", "class Foo; def initialize; instance_variable_set(:@bar, 14); end; end; puts Foo.new.instance_variable_defined?(\"@bar\")"); - assertPrints("false\n", "class Foo; def initialize; @foo=14; end; end; puts Foo.new.instance_variable_defined?(:@bar)"); - assertPrints("false\n", "class Foo; def initialize; @foo=14; end; end; puts Foo.new.instance_variable_defined?(\"@bar\")"); - assertPrints("false\n", "class Foo; def initialize; instance_variable_set(:@foo, 14); end; end; puts Foo.new.instance_variable_defined?(\"@bar\")"); - } - - @Test - public void testInstanceVariableGet() { - assertPrints("14\n", "class Foo; def initialize; @bar=14; end; end; puts Foo.new.instance_variable_get(:@bar)"); - assertPrints("14\n", "class Foo; def initialize; @bar=14; end; end; puts Foo.new.instance_variable_get(\"@bar\")"); - } - - @Test - public void testInstanceVariableSet() { - assertPrints("14\n", "class Foo; attr_accessor :bar; end; foo = Foo.new; foo.instance_variable_set(:@bar, 14); puts foo.bar"); - assertPrints("14\n", "class Foo; attr_accessor :bar; end; foo = Foo.new; foo.instance_variable_set(\"@bar\", 14); puts foo.bar"); - } - - @Test - public void testInstanceVariables() { - assertPrints("a\nb\n", "class Foo; def initialize; @a=2; @b=14; end; end; puts Foo.new.instance_variables"); - assertPrints("a\nb\n", "class Foo; def initialize; @a=2; instance_variable_set(:@b, 14); end; end; puts Foo.new.instance_variables"); - } - - @Test - public void testSend() { - assertPrints("14\n", "self.send(:puts, 14)"); - assertPrints("14\n", "self.send(\"puts\", 14)"); - } - - @Test - public void testExtend() { - assertPrints("14\n", "class Foo; end; module Bar; def bar; puts 14; end; end; foo = Foo.new; foo.extend(Bar); foo.bar"); - } - - @Test - public void testSingletonMethods() { - assertPrints("[:baz]\n", "class Foo; def bar; end; end; foo = Foo.new; def foo.baz; end; puts foo.singleton_methods.to_s"); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/ProcTests.java --- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/ProcTests.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.test.core; - -import org.junit.*; - -import com.oracle.truffle.ruby.test.*; - -/** - * Test the {@code Proc} class. - */ -public class ProcTests extends RubyTests { - - @Test - public void testKernelProc() { - assertPrints("1\n", "x = proc { puts 1 }; x.call"); - assertPrints("1\n", "x = proc { 1 }; puts x.call"); - } - - @Test - public void testKernelLambda() { - assertPrints("1\n", "x = lambda { puts 1 }; x.call"); - assertPrints("1\n", "x = lambda { 1 }; puts x.call"); - } - - @Test - public void testKernelProcNew() { - assertPrints("1\n", "x = Proc.new { puts 1 }; x.call"); - assertPrints("1\n", "x = Proc.new { 1 }; puts x.call"); - } - - @Test - public void testProcReturn() { - assertPrints("1\n", "def foo; x = proc { return 1 }; x.call; return 2; end; puts foo"); - } - - @Test - public void testLambdaReturn() { - assertPrints("2\n", "def foo; x = lambda { return 1 }; x.call; return 2; end; puts foo"); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/RangeTests.java --- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/RangeTests.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.test.core; - -import org.junit.*; - -import com.oracle.truffle.ruby.test.*; - -/** - * Test the {@code Range} class. - */ -public class RangeTests extends RubyTests { - - @Test - public void testImmediate() { - assertPrints("1..2\n", "puts 1..2"); - assertPrints("1..2\n", "puts (1..2)"); - assertPrints("1..2\n", "puts ((1)..2)"); - assertPrints("1...2\n", "puts 1...2"); - } - - @Test - public void testVariables() { - assertPrints("1..2\n", "x = 1; puts x..2"); - assertPrints("1..2\n", "y = 2; puts 1..y"); - assertPrints("1..2\n", "x = 1; y = 2; puts x..y"); - } - - @Test - public void testToArray() { - assertPrints("0\n1\n2\n", "puts (0..2).to_a"); - assertPrints("1\n2\n", "puts (1..2).to_a"); - assertPrints("1\n2\n", "puts (1...3).to_a"); - assertPrints("1\n2\n3\n", "puts (1..3).to_a"); - } - - @Test - public void testEach() { - assertPrints("", "(1...1).each { |n| puts n }"); - assertPrints("1\n", "(1...2).each { |n| puts n }"); - assertPrints("1\n2\n", "(1...3).each { |n| puts n }"); - assertPrints("1\n2\n3\n", "(1...4).each { |n| puts n }"); - assertPrints("1\n", "(1..1).each { |n| puts n }"); - assertPrints("1\n2\n", "(1..2).each { |n| puts n }"); - assertPrints("1\n2\n3\n", "(1..3).each { |n| puts n }"); - assertPrints("1\n2\n3\n4\n", "(1..4).each { |n| puts n }"); - assertPrints("0\n1\n", "(0..1).each { |n| puts n }"); - assertPrints("", "(4..-2).each { |n| puts n }"); - assertPrints("-4\n-3\n-2\n", "(-4..-2).each { |n| puts n }"); - assertPrints("-1\n0\n1\n", "(-1..1).each { |n| puts n }"); - } - - @Test - public void testMap() { - assertPrints("2\n4\n6\n", "puts (1..3).map { |n| n*2 }"); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/RegexpTests.java --- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/RegexpTests.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.test.core; - -import org.junit.*; - -import com.oracle.truffle.ruby.test.*; - -/** - * Test the {@code Regexp} class. - */ -public class RegexpTests extends RubyTests { - - @Test - public void testLiteral() { - assertPrints("Regexp\n", "puts /foo/.class"); - } - - @Test - public void testInterpolatedLiteral() { - assertPrints("Regexp\n", "puts /foo#{1}/.class"); - } - - @Test - public void testMatch() { - assertPrints("0\n", "puts(/foo/ =~ \"foo\")"); - assertPrints("0\n", "puts(\"foo\" =~ /foo/)"); - assertPrints("3\n", "puts(/foo/ =~ \"abcfoo\")"); - assertPrints("3\n", "puts(\"abcfoo\" =~ /foo/)"); - assertPrints("\n", "puts(/foo/ =~ \"abc\")"); - assertPrints("\n", "puts(\"abc\" =~ /foo/)"); - } - - @Test - public void testFrameLocalVariableResults() { - assertPrints("foo\nbar\nbaz\n", "/(foo)(bar)(baz)/ =~ 'foobarbaz'; puts $1; puts $2; puts $3"); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/StringTests.java --- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/StringTests.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.test.core; - -import org.junit.*; - -import com.oracle.truffle.ruby.test.*; - -/** - * Test the {@code String} class. - */ -public class StringTests extends RubyTests { - - @Test - public void testToI() { - assertPrints("2\n", "puts \"2\".to_i"); - assertPrints("-2\n", "puts \"-2\".to_i"); - assertPrints("123456789123456789\n", "puts \"123456789123456789\".to_i"); - } - - @Test - public void testFormat() { - assertPrints("a\n", "puts \"a\""); - assertPrints("1\n", "puts \"%d\" % 1"); - assertPrints("a1b\n", "puts \"a%db\" % 1"); - assertPrints("a1.00000b\n", "puts \"a%fb\" % 1"); - assertPrints("a2.50000b\n", "puts \"a%fb\" % 2.5"); - assertPrints("3.400000000\n", "puts \"%.9f\" % 3.4"); - assertPrints("3.400000000\n", "puts \"%0.9f\" % 3.4"); - } - - @Test - public void testThreequal() { - assertPrints("false\n", "puts \"a\" === \"b\""); - assertPrints("true\n", "puts \"a\" === \"a\""); - } - - @Test - public void testIndex() { - assertPrints("a\n", "puts 'a'[0]"); - assertPrints("config\n", "puts 'foo.config'[-6..-1]"); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/SymbolTests.java --- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/SymbolTests.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.test.core; - -import org.junit.*; - -import com.oracle.truffle.ruby.test.*; - -/** - * Test the {@code Symbol} class. - */ -public class SymbolTests extends RubyTests { - - @Test - public void testParses() { - assertPrints("", ":foo"); - assertPrints("", ":\"foo\""); - } - - @Test - public void testPuts() { - assertPrints("foo\n", "puts :foo"); - } - - @Test - public void testInterpolated() { - assertPrints("foo123\n", "puts :\"foo1#{2}3\""); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/ThreadTests.java --- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/core/ThreadTests.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.test.core; - -import org.junit.*; - -import com.oracle.truffle.ruby.test.*; - -/** - * Test the {@code Thread} class. - */ -public class ThreadTests extends RubyTests { - - @Test - public void testCreateJoin() { - assertPrints("1\n2\n", "t = Thread.new { puts 1 }; t.join; puts 2"); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/AndTests.java --- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/AndTests.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.test.language; - -import org.junit.*; - -import com.oracle.truffle.ruby.test.*; - -/** - * Test {@code and} expressions, which unusually for Ruby are not methods. This is because with - * Ruby's eager evaluation there would be no way to implement the short circuit semantics. - */ -public class AndTests extends RubyTests { - - @Test - public void testImmediate() { - assertPrints("false\n", "puts false && false"); - assertPrints("false\n", "puts true && false"); - assertPrints("false\n", "puts false && true"); - assertPrints("true\n", "puts true && true"); - assertPrints("false\n", "puts (false and false)"); - assertPrints("false\n", "puts (true and false)"); - assertPrints("false\n", "puts (false and true)"); - assertPrints("true\n", "puts (true and true)"); - } - - @Test - public void testShortCircuits() { - assertPrints("false\nfalse\nfalse\n", "x = y = false; puts (x = false) && (y = false); puts x, y"); - assertPrints("false\ntrue\nfalse\n", "x = y = false; puts (x = true) && (y = false); puts x, y"); - assertPrints("false\nfalse\nfalse\n", "x = y = false; puts (x = false) && (y = true); puts x, y"); - assertPrints("true\ntrue\ntrue\n", "x = y = false; puts (x = true) && (y = true); puts x, y"); - assertPrints("false\nfalse\nfalse\n", "x = y = false; puts ((x = false) and (y = false)); puts x, y"); - assertPrints("false\ntrue\nfalse\n", "x = y = false; puts ((x = true) and (y = false)); puts x, y"); - assertPrints("false\nfalse\nfalse\n", "x = y = false; puts ((x = false) and (y = true)); puts x, y"); - assertPrints("true\ntrue\ntrue\n", "x = y = false; puts ((x = true) and (y = true)); puts x, y"); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/BlockTests.java --- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/BlockTests.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.test.language; - -import org.junit.*; - -import com.oracle.truffle.ruby.test.*; - -/** - * Test blocks. - */ -public class BlockTests extends RubyTests { - - @Test - public void testSimpleYield() { - assertPrints("1\n", "def foo; yield; end; foo { puts 1 };"); - assertPrints("1\n", "def foo; yield; end; foo do; puts 1; end;"); - } - - @Test - public void testYieldOneParameter() { - assertPrints("1\n", "def foo; yield 1; end; foo { |x| puts x };"); - assertPrints("1\n", "def foo; yield 1; end; foo do |x|; puts x; end;"); - } - - @Test - public void testYieldTwoParameters() { - assertPrints("1\n2\n", "def foo; yield 1, 2; end; foo { |x, y| puts x; puts y; };"); - assertPrints("1\n2\n", "def foo; yield 1, 2; end; foo do |x, y|; puts x; puts y; end;"); - } - - @Test - public void testSelfCapturedInBlock() { - assertPrints("main\n", "[1].each { |n| puts self.to_s }"); - } - - @Test - public void testBlockArgumentsDestructure() { - /* - * This really subtle. If you pass an array to a block with more than one parameters, it - * will be destructured. Any other type won't be destructured. There's no annotation to - * indicate that, like there would be with a method with the * operator. - */ - - assertPrints("1\n", "[1].each { |x| puts x.to_s }"); - assertPrints("[1, 2]\n", "[[1, 2]].each { |xy| puts xy.to_s }"); - assertPrints("1\n2\n", "[[1, 2]].each { |x, y| puts x, y }"); - } - - @Test - public void testBlocksHaveTheirOwnScopeForAssignment() { - assertPrints("\n", "1.times { x = 14 }; puts defined? x"); - assertPrints("\n", "1.times do; x = 14; end; puts defined? x"); - } - - @Test - public void testImplicitForBlocksDoNotHaveTheirOwnScopeForAssignment() { - assertPrints("local-variable\n", "for n in [1]; x = 14; end; puts defined? x"); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/CaseTests.java --- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/CaseTests.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.test.language; - -import org.junit.*; - -import com.oracle.truffle.ruby.test.*; - -/** - * Test {@code case} expressions. - */ -public class CaseTests extends RubyTests { - - @Test - public void testSingle() { - assertPrints("1\n4\n", "case 'a'; when 'a'; puts 1; when 'b'; puts 2; else; puts 3; end; puts 4"); - assertPrints("2\n4\n", "case 'b'; when 'a'; puts 1; when 'b'; puts 2; else; puts 3; end; puts 4"); - assertPrints("3\n4\n", "case 'c'; when 'a'; puts 1; when 'b'; puts 2; else; puts 3; end; puts 4"); - } - - @Test - public void testMultiple() { - assertPrints("1\n4\n", "case 'a'; when 'a', 'b'; puts 1; when 'c'; puts 2; else; puts 3; end; puts 4"); - assertPrints("1\n4\n", "case 'b'; when 'a', 'b'; puts 1; when 'c'; puts 2; else; puts 3; end; puts 4"); - assertPrints("2\n4\n", "case 'c'; when 'a', 'b'; puts 1; when 'c'; puts 2; else; puts 3; end; puts 4"); - assertPrints("3\n4\n", "case 'd'; when 'a', 'b'; puts 1; when 'c'; puts 2; else; puts 3; end; puts 4"); - } - - @Test - public void testSimpleConditions() { - assertPrints("1\n", "case; when true; puts 1; when false; puts 2; end"); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/ClassLocalTests.java --- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/ClassLocalTests.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.test.language; - -import org.junit.*; - -import com.oracle.truffle.ruby.test.*; - -/** - * Test @@ class variables. There is a lot of counter-intuitive behavior here - they aren't instance - * variables in class objects. The books describe them as being in a 'class hierarchy', rather than - * in a class. Also, the object they are defined it is not consistent - sometimes it is the class of - * self, sometimes it's just self. - */ -public class ClassLocalTests extends RubyTests { - - @Test - public void testBasic() { - assertPrints("14\n", "@@x = 14; puts @@x"); - } - - /* - * Test that they are defined for a hierarchy, not a class. - */ - - @Test - public void testHeirarchyNotClassVariable() { - assertPrints("2\n", "class Foo; @@value = 14; end; class Bar < Foo; @@value = 2; end; class Foo; puts @@value; end"); - } - - /* - * Test that they take the correct class at different times. In a method, they use the class of - * self. In a class definition they use that class, not the class of self, which is Class. - */ - - @Test - public void testCorrectClass() { - assertPrints("1\n", "class Foo; @@x = 1; def foo; puts @@x; end; end; Foo.new.foo"); - } - - @Test - public void testWithinSelfMethod() { - assertPrints("14\n", "class Foo; @@foo = 14; def self.foo; @@foo; end; end; puts Foo.foo"); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/ClassTests.java --- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/ClassTests.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.test.language; - -import org.junit.*; - -import com.oracle.truffle.ruby.test.*; - -/** - * Test {@code class} expressions. - */ -public class ClassTests extends RubyTests { - - @Test - public void testDefine() { - assertPrints("Foo\n", "class Foo; end; puts Foo"); - } - - @Test - public void testMethods() { - assertPrints("14\n", "class Foo; def test; return 14; end; end; foo=Foo.new; puts foo.test"); - assertPrints("14\n", "class Foo; def test(x); return x; end; end; foo=Foo.new; puts foo.test(14)"); - } - - @Test - public void testDefineHasScope() { - assertPrints("14\n", "x=14; class Foo; x=0; end; puts x"); - assertPrints("14\n", "class Foo; x=14; puts x; end"); - } - - @Test - public void testInitialise() { - assertPrints("14\n", "class Foo; def initialize; puts 14; end; end; Foo.new"); - assertPrints("14\n", "class Foo; def initialize(x); puts x; end; end; Foo.new 14"); - assertPrints("14\n", "class Foo; def initialize(x); puts x; end; end; Foo.new(14)"); - } - - @Test - public void testInstanceVariables() { - assertPrints("14\n", "class Foo; def a; @x=14; end; def b; @x; end; end; foo=Foo.new; foo.a; puts foo.b"); - } - - @Test - public void testMissingVariables() { - assertPrints("NilClass\n", "class Foo; def a; @x; end; end; foo=Foo.new; puts foo.a.class"); - } - - @Test - public void testClassConstants() { - assertPrints("14\n", "class Foo; X=14; def foo; puts X; end; end; foo=Foo.new; foo.foo"); - } - - @Test - public void testReopeningSingletonClass() { - assertPrints("1\n", "foo = Object.new; class << foo; def bar; puts 1; end; end; foo.bar"); - } - - @Test - public void testInheritance() { - assertPrints("14\n", "class Foo; def foo; puts 14; end; end; class Bar < Foo; end; Bar.new.foo"); - } - - @Test - public void testSingletonInheritance() { - assertPrints("14\n", "class Foo; def self.foo; puts 14; end; end; class Bar < Foo; end; Bar.foo"); - } - - @Test - public void testNestedClass() { - assertPrints("14\n", "class Foo; class Bar; def bar; 14; end; end; def foo; Bar.new; end; end; puts Foo.new.foo.bar"); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/ConstantTests.java --- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/ConstantTests.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.test.language; - -import org.junit.*; - -import com.oracle.truffle.ruby.test.*; - -public class ConstantTests extends RubyTests { - - @Test - public void testTopLevelConstants() { - assertPrints("14\n", "X=14; class Foo; def foo; puts X; end; end; f=Foo.new; f.foo"); - } - - @Test - public void testNestedConstants() { - assertPrints("", "module X; class A; end; class B; class C < A; end; end; end"); - } - - @Test - public void testSearchInParentModules() { - assertPrints("14\n", "module A; C = 14; module B; def self.test; puts C; end; end; end; A::B.test"); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/ForTests.java --- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/ForTests.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.test.language; - -import org.junit.*; - -import com.oracle.truffle.ruby.test.*; - -/** - * Test {@code for} expressions. - */ -public class ForTests extends RubyTests { - - @Test - public void testArray() { - assertPrints("1\n2\n3\n", "for x in [1, 2, 3]; puts x; end"); - assertPrints("1\n2\n3\n", "y = [1, 2, 3]; for x in y; puts x; end"); - } - - @Test - public void testRange() { - assertPrints("1\n2\n3\n", "for x in 1..3; puts x; end"); - assertPrints("1\n2\n3\n", "y = 1..3; for x in y; puts x; end"); - assertPrints("1\n2\n", "for x in 1...3; puts x; end"); - } - - @Test - public void testScopeRO() { - assertPrints("14\n", "x=14; for n in [1]; puts x; end"); - } - - @Test - public void testScopeRW() { - assertPrints("14\n", "x=0; for n in [1]; x=x+14; puts x; end"); - } - - @Test - public void testNoNewScope() { - assertPrints("14\n", "for i in [1]; v = 14; end; puts v"); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/GlobalVariableTests.java --- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/GlobalVariableTests.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.test.language; - -import org.junit.*; - -import com.oracle.truffle.ruby.test.*; - -/** - * Test global variables. - */ -public class GlobalVariableTests extends RubyTests { - - @Test - public void testMinimal() { - assertPrints("14\n", "$foo = 14; puts $foo"); - } - - @Test - public void testScope() { - assertPrints("14\n", "def foo; $bar = 14; end; foo; puts $bar"); - assertPrints("14\n", "$bar = 14; def foo; puts $bar; end; foo"); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/IfTests.java --- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/IfTests.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.test.language; - -import org.junit.*; - -import com.oracle.truffle.ruby.test.*; - -/** - * Test {@code if} expressions. - */ -public class IfTests extends RubyTests { - - @Test - public void testImmediateIf() { - assertPrints("1\n", "if true; puts 1 end"); - assertPrints("", "if false; puts 1 end"); - } - - @Test - public void testImmediateTrailingIf() { - assertPrints("1\n", "puts 1 if true"); - assertPrints("", "puts 1 if false"); - } - - @Test - public void testImmediateIfElse() { - assertPrints("1\n", "if true; puts 1 else puts 2 end"); - assertPrints("2\n", "if false; puts 1 else puts 2 end"); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/InterpolatedStringTests.java --- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/InterpolatedStringTests.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.test.language; - -import org.junit.*; - -import com.oracle.truffle.ruby.test.*; - -/** - * Test interpolated strings - that is string literals with #{...} sections in them. Within those - * you can have arbitrary Ruby expressions. - */ -public class InterpolatedStringTests extends RubyTests { - - @Test - public void testBasic() { - assertPrints("123\n", "puts \"1#{2}3\""); - } - - @Test - public void testMethodCall() { - assertPrints("123\n", "def foo; 2; end; puts \"1#{foo}3\""); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/LocalTests.java --- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/LocalTests.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.test.language; - -import org.junit.*; - -import com.oracle.truffle.ruby.test.*; - -/** - * Test local variables. - */ -public class LocalTests extends RubyTests { - - @Test - public void testAssignmentTopLevel() { - assertPrints("1\n", "x = 1; puts x"); - } - - @Test - public void testAssignmentWithinMethod() { - assertPrints("1\n", "def foo; x = 1; puts x; end; foo"); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/MethodTests.java --- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/MethodTests.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,251 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.test.language; - -import org.junit.*; - -import com.oracle.truffle.ruby.runtime.control.*; -import com.oracle.truffle.ruby.test.*; - -/** - * Test method definitions and calls. - */ -public class MethodTests extends RubyTests { - - @Test - public void testDefineCallNoArguments() { - assertPrints("1\n", "def foo; puts 1; end; foo()"); - assertPrints("1\n", "def foo; puts 1; end; foo"); - } - - @Test - public void testDefineCallOnePreArgument() { - assertPrints("1\n", "def foo(a); puts a; end; foo(1)"); - assertPrints("1\n", "def foo(a); puts a; end; foo 1"); - } - - @Test - public void testDefineCallTwoPreArguments() { - assertPrints("1\n2\n", "def foo(a, b); puts a; puts b; end; foo(1, 2)"); - assertPrints("1\n2\n", "def foo(a, b); puts a; puts b; end; foo 1, 2"); - } - - @Test - public void testSingleReturn() { - assertPrints("1\n", "def foo; return 1; end; puts foo"); - assertPrints("1\n", "def foo(n); return n; end; puts foo(1)"); - } - - @Test - public void testImplicitReturn() { - assertPrints("1\n", "def foo; 1; end; puts foo"); - assertPrints("3\n", "def foo; 1+2; end; puts foo"); - assertPrints("14\n", "def foo; x=14; end; puts foo"); - } - - @Test - public void testNestedCall() { - assertPrints("1\n", "def foo(n); return n; end; def bar(n); return foo(n); end; puts bar(1)"); - assertPrints("1\n1\n1\n", "def foo(n); puts n; return n; end; def bar(n); puts n; return foo(n); end; puts bar(1)"); - assertPrints("1\n1\n", "def foo(a, b); puts a; puts b; end; def bar(n); foo(n, n); end; bar(1)"); - } - - @Test - public void testNestedOperatorCall() { - assertPrints("3\n", "def foo(a, b); puts a + b; end; foo(1, 2)"); - } - - /** - * Tests that arguments are evaluated before method dispatch takes place, by putting an action - * in one of the arguments that modifies the method that we should find in dispatch. - */ - @Test - public void testArgumentsExecutedBeforeDispatch() { - /* - * We have to use Object#send instead of calling define_method directly because that method - * is private. - */ - - assertPrints("12\n", "def foo\n" + // - " Fixnum.send(:define_method, :+) do |other|\n" + // - " self - other\n" + // - " end \n" + // - " 2\n" + // - "end\n" + // - "puts 14 + foo"); - } - - @Test(expected = RaiseException.class) - public void testTooFewArguments1() { - assertPrints("", "def foo(a); end; foo()"); - } - - @Test(expected = RaiseException.class) - public void testTooFewArguments2() { - assertPrints("", "def foo(a, b); end; foo(1)"); - } - - @Test(expected = RaiseException.class) - public void testTooFewArguments3() { - assertPrints("", "def foo(a, b, c); end; foo(1, 2)"); - } - - @Test(expected = RaiseException.class) - public void testTooManyArguments1() { - assertPrints("", "def foo(); end; foo(1)"); - } - - @Test(expected = RaiseException.class) - public void testTooManyArguments2() { - assertPrints("", "def foo(a); end; foo(1, 2)"); - } - - @Test(expected = RaiseException.class) - public void testTooManyArguments3() { - assertPrints("", "def foo(a, b); end; foo(1, 2, 3)"); - } - - @Test - public void testPolymophicMethod() { - assertPrints("A\nB\n", "class A\n" + // - " def foo\n" + // - " puts \"A\"\n" + // - " end\n" + // - "end\n" + // - "\n" + // - "class B\n" + // - " def foo\n" + // - " puts \"B\"\n" + // - " end\n" + // - "end\n" + // - "\n" + // - "def bar(x)\n" + // - " x.foo\n" + // - "end\n" + // - "\n" + // - "a = A.new\n" + // - "b = B.new\n" + // - "\n" + // - "bar(a)\n" + // - "bar(b)\n"); - } - - @Test - public void testOneDefaultValue() { - assertPrints("1\n2\n", "def foo(a=1); puts a; end; foo; foo(2)"); - } - - @Test - public void testTwoDefaultValues() { - assertPrints("1\n2\n3\n2\n3\n4\n", "def foo(a=1,b=2); puts a; puts b; end; foo; foo(3); foo(3, 4)"); - } - - @Test - public void testOneDefaultValueAfterNonDefault() { - assertPrints("2\n1\n2\n3\n", "def foo(a, b=1); puts a; puts b; end; foo(2); foo(2, 3)"); - } - - @Test - public void testOneDefaultValueBeforeNonDefault() { - assertPrints("1\n2\n2\n3\n", "def foo(a=1, b); puts a; puts b; end; foo(2); foo(2, 3)"); - } - - @Test - public void testBlockArgument() { - assertPrints("1\n2\n3\n", "def foo(&block); block.call(14); end; puts 1; foo { |n| puts 2 }; puts 3"); - } - - @Test - public void testBlockArgumentWithOthers() { - assertPrints("1\n2\n3\n4\n5\n", "def foo(a, b, &block); puts a; block.call(14); puts b; end; puts 1; foo(2, 4) { |n| puts 3 }; puts 5"); - } - - @Test - public void testBlockPass() { - assertPrints("1\n2\n3\n", "def bar; yield; end; def foo(&block); bar(&block); end; puts 1; foo { puts 2 }; puts 3"); - } - - @Test - public void testBlockPassWithOthers() { - assertPrints("1\n2\n3\n4\n5\n", "def bar(a, b); puts a; yield; puts b; end; def foo(a, b, &block); bar(a, b, &block); end; puts 1; foo(2, 4) { puts 3 }; puts 5"); - } - - @Test - public void testSplatWhole() { - assertPrints("1\n2\n3\n", "def foo(a, b, c); puts a; puts b; puts c; end; d = [1, 2, 3]; foo(*d)"); - } - - @Test - public void testSplatSome() { - assertPrints("1\n2\n3\n", "def foo(a, b, c); puts a; puts b; puts c; end; d = [2, 3]; foo(1, *d)"); - } - - @Test - public void testSplatParam() { - assertPrints("[1, 2, 3]\n", "def foo(*bar); puts bar.to_s; end; foo(1, 2, 3)"); - } - - @Test - public void testSplatParamWithOther() { - assertPrints("1\n[2]\n", "def foo(a, *b); puts a.to_s; puts b.to_s; end; foo(1, 2)"); - } - - @Test - public void testSplatParamWithBlockPass() { - assertPrints("[1, 2, 3]\n", "def foo(*bar, &block); block.call(bar); end; foo(1, 2, 3) { |x| puts x.to_s }"); - } - - @Test - public void testSingletonMethod() { - assertPrints("1\n", "foo = Object.new; def foo.bar; puts 1; end; foo.bar"); - } - - @Test - public void testAlias() { - assertPrints("1\n", "def foo; puts 1; end; alias bar foo; bar"); - assertPrints("1\n", "class Foo; def foo; puts 1; end; alias bar foo; end; Foo.new.bar"); - } - - @Test - public void testAliasMethod() { - assertPrints("1\n", "class Foo; def foo; puts 1; end; alias_method :bar, :foo; end; Foo.new.bar"); - } - - @Test - public void testSymbolAsBlock() { - assertPrints("6\n", "puts [1, 2, 3].inject(&:+)"); - } - - @Test - public void testSuper() { - assertPrints("1\n2\n3\n", "class Foo; def foo; puts 2; end; end; class Bar < Foo; def foo; puts 1; super; puts 3; end; end; Bar.new.foo"); - } - - @Test - public void testSuperWithArgs() { - assertPrints("1\n2\n3\n", "class Foo; def foo(n); puts n; end; end; class Bar < Foo; def foo(n); puts 1; super(n); puts 3; end; end; Bar.new.foo(2)"); - } - - @Test - public void testPushSplat() { - assertPrints("[1, 0, 4]\n", "a = [1, 2, 3, 4]; b = [1, 2]; a[*b] = 0; puts a.to_s"); - } - - @Test - public void testBlocksPassedIntoBlocks() { - assertPrints("14\n", "def foo; 1.times do; yield; end; end; foo do; puts 14; end"); - } - - @Test - public void testBlocksNotPassedIntoFullMethods() { - assertPrints("no block\n", "def foo(&block); if block; puts 'block'; else; puts 'no block'; end; end; def bar; foo; end; bar do; end"); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/ModuleTests.java --- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/ModuleTests.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.test.language; - -import org.junit.*; - -import com.oracle.truffle.ruby.test.*; - -/** - * Test {@code module} expressions. - */ -public class ModuleTests extends RubyTests { - - @Test - public void testDefine() { - assertPrints("Foo\n", "module Foo; end; puts Foo"); - } - - @Test - public void testWithConstantDefinition() { - assertPrints("14\n", "module Foo; FOO=14; end; puts Foo::FOO"); - } - - @Test - public void testWithConstantDefinitionAndAccessInDeclaration() { - assertPrints("14\n", "module Foo; FOO=14; puts FOO; end"); - } - - @Test - public void testCanAccessObjectConstantsInModuleDefinition() { - assertPrints("", "class Foo; end; module Bar; foo = Foo.new; end"); - } - - @Test - public void testInclude() { - assertPrints("14\n", "module Foo; FOO=14; end; module Bar; include Foo; end; puts Bar::FOO"); - } - - @Test - public void testModuleFunction() { - assertPrints("1\n", "module Foo; def bar; puts 1; end; module_function :bar; end; Foo::bar"); - } - - @Test - public void testDistinctModule() { - assertPrints("true\n", "module A; module X; end; end; module B; module X; end; end; puts A::X.object_id != B::X.object_id"); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/MultipleAssignmentTests.java --- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/MultipleAssignmentTests.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.test.language; - -import org.junit.*; - -import com.oracle.truffle.ruby.test.*; - -/** - * Test multiple assignment, which is sort of like pattern matching for arrays. The arrays can be - * implicit on the RHS. - */ -public class MultipleAssignmentTests extends RubyTests { - - @Test - public void testToLocal() { - assertPrints("1\n2\n", "x, y = [1, 2]; puts x, y"); - assertPrints("1\n2\n", "x, y = 1, 2; puts x, y"); - assertPrints("1\n2\n", "x = [1, 2]; y, z = x; puts y, z"); - } - - @Test - public void testToArrayIndex() { - assertPrints("1\n2\n", "x = []; x[0], x[1] = 1, 2; puts x"); - } - - @Test - public void testSwap() { - assertPrints("2\n1\n", "a = [1]; b = [2]; a[0], b[0] = b[0], a[0]; puts a, b"); - } - - @Test - public void testProducesArray() { - assertPrints("1\n2\n", "puts((a, b = 1, 2))"); - } - - @Test - public void testWithSplat() { - assertPrints("1\n[2, 3]\n", "a, *b = [1, 2, 3]; puts a; puts b.to_s"); - } - - @Test - public void testWithSplatEmpty() { - assertPrints("1\n[]\n", "a, *b = [1]; puts a.to_s; puts b.to_s"); - } - - @Test - public void testWithSingleValueRHS() { - assertPrints("14\n\n\n", "a, b, c = 14; puts a; puts b; puts c"); - assertPrints("\n\n\n", "a, b, c = nil; puts a; puts b; puts c"); - } - - @Test - public void testWithSingleSplatLHSAndSingleValueRHS() { - assertPrints("[14]\n", "a = *14; puts a.to_s"); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/OrTests.java --- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/OrTests.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.test.language; - -import org.junit.*; - -import com.oracle.truffle.ruby.test.*; - -/** - * Test {@code or} expressions, which unusually for Ruby are not methods. This is because with - * Ruby's eager evaluation there would be no way to implement the short circuit semantics. - */ -public class OrTests extends RubyTests { - - @Test - public void testImmediate() { - assertPrints("false\n", "puts false || false"); - assertPrints("true\n", "puts true || false"); - assertPrints("true\n", "puts false || true"); - assertPrints("true\n", "puts true || true"); - assertPrints("false\n", "puts (false or false)"); - assertPrints("true\n", "puts (true or false)"); - assertPrints("true\n", "puts (false or true)"); - assertPrints("true\n", "puts (true or true)"); - } - - @Test - public void testShortCircuits() { - assertPrints("false\nfalse\nfalse\n", "x = y = false; puts (x = false) || (y = false); puts x, y"); - assertPrints("true\ntrue\nfalse\n", "x = y = false; puts (x = true) || (y = false); puts x, y"); - assertPrints("true\nfalse\ntrue\n", "x = y = false; puts (x = false) || (y = true); puts x, y"); - assertPrints("true\ntrue\nfalse\n", "x = y = false; puts (x = true) || (y = true); puts x, y"); - assertPrints("false\nfalse\nfalse\n", "x = y = false; puts ((x = false) or (y = false)); puts x, y"); - assertPrints("true\ntrue\nfalse\n", "x = y = false; puts ((x = true) or (y = false)); puts x, y"); - assertPrints("true\nfalse\ntrue\n", "x = y = false; puts ((x = false) or (y = true)); puts x, y"); - assertPrints("true\ntrue\nfalse\n", "x = y = false; puts ((x = true) or (y = true)); puts x, y"); - } - - @Test - public void testOrAssign() { - assertPrints("true\n", "def foo; puts 1; false; end; x = true; x ||= foo; puts x"); - assertPrints("1\nfalse\n", "def foo; puts 1; false; end; x = false; x ||= foo; puts x"); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/PolymorphismTests.java --- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/PolymorphismTests.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.test.language; - -import org.junit.*; - -import com.oracle.truffle.ruby.test.*; - -/** - * Test characteristics of polymorphism. - */ -public class PolymorphismTests extends RubyTests { - - /** - * Test that a polymorphic method that will specialize to double will then not treat integers as - * doubles. - */ - @Test - public void testSimpleOperatorRedefinition() { - assertPrints("16.759999999999998\n16\n", // - "def add(x, y)\n" + // - " x + y\n" + // - "end\n" + // - "puts add(14.5, 2.26)\n" + // - "puts add(14, 2)\n"); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/RaiseRescueTests.java --- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/RaiseRescueTests.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.test.language; - -import org.junit.*; - -import com.oracle.truffle.ruby.runtime.control.*; -import com.oracle.truffle.ruby.test.*; - -/** - * Test {@code raise} and {@code rescue}. - */ -public class RaiseRescueTests extends RubyTests { - - @Test(expected = RaiseException.class) - public void testZeroDivisionError() { - assertPrints("", "1/0"); - } - - @Test - public void testBeginRescue() { - assertPrints("", "begin; rescue; end"); - assertPrints("", "begin; rescue => e; end"); - assertPrints("", "begin; rescue ZeroDivisionError => e; end"); - assertPrints("", "begin; rescue; ensure; end"); - assertPrints("", "begin; rescue => e; ensure; end"); - assertPrints("", "begin; rescue ZeroDivisionError => e; ensure; end"); - assertPrints("", "begin; rescue; else; end"); - assertPrints("", "begin; rescue => e; else; end"); - assertPrints("", "begin; rescue ZeroDivisionError => e; else; end"); - assertPrints("", "def foo; rescue; end"); - assertPrints("", "def foo; rescue => e; end"); - assertPrints("", "def foo; rescue ZeroDivisionError => e; end"); - assertPrints("", "def foo; rescue; ensure; end"); - assertPrints("", "def foo; rescue => e; ensure; end"); - assertPrints("", "def foo; rescue ZeroDivisionError => e; ensure; end"); - assertPrints("", "def foo; rescue; else; end"); - assertPrints("", "def foo; rescue => e; else; end"); - assertPrints("", "def foo; rescue ZeroDivisionError => e; else; end"); - } - - @Test - public void testRescueZeroDivisionError() { - assertPrints("divided by 0\n3\n4\n", "begin; 1/0; puts 1; rescue => e; puts e; else puts 2; ensure puts 3; end; puts 4"); - assertPrints("divided by 0\n3\n4\n", "begin; 1/0; puts 1; rescue ZeroDivisionError => e; puts e; else puts 2; ensure puts 3; end; puts 4"); - assertPrints("1\n2\n3\n4\n", "begin; 1/1; puts 1; rescue ZeroDivisionError => e; puts e; else puts 2; ensure puts 3; end; puts 4"); - assertPrints("1\n2\n3\n4\n", "begin; 1/1; puts 1; rescue ZeroDivisionError => e; puts e; rescue NameError => e; puts e; else puts 2; ensure puts 3; end; puts 4"); - } - - @Test - public void testSplatRescue() { - assertPrints("2\n", "ERRORS=[ZeroDivisionError]; begin; 1/0; puts 1; rescue *ERRORS; puts 2; end"); - } - - @Test - public void testRetry() { - assertPrints("1\n3\n1\n2\n5\n", "x=0; begin; puts 1; 1/x; puts 2; rescue ZeroDivisionError; puts 3; x=1; retry; puts 4; end; puts 5"); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/RedefinitionTests.java --- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/RedefinitionTests.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.test.language; - -import org.junit.*; - -import com.oracle.truffle.ruby.test.*; - -/** - * Test that methods can be redefined. - */ -public class RedefinitionTests extends RubyTests { - - /** - * Test that a method on Fixnum can be redefined and that we will use the new definition. The - * call that expects to find the redefinition needs to have already been specialized, which is - * why do it through a method. - */ - @Test - public void testSimpleOperatorRedefinition() { - assertPrints("3\n-1\n", // - "def add(x, y)\n" + // - " x + y\n" + // - "end\n" + // - "puts add(1, 2)\n" + // - "class Fixnum\n" + // - " def +(other)\n" + // - " self - other\n" + // - " end\n" + // - "end\n" + // - "puts add(1, 2)\n"); - } - - /** - * This is quite a subtle test. We redefine Float#+. We have a method which calls +. It is - * initially specialized to Fixnum, but then used with Float. The tricky bit is that Float has - * not been redefined since the operator has been specialized. The operator thinks it is up to - * date. When we emit a + node, we need to check if any class that that node could specialize to - * has been redefined. - */ - @Test - public void testSpecialisationConsidersRedefinitionInOtherClasses() { - assertPrints("16\n12.25\n", // - "def add(a, b)\n" + // - " a + b\n" + // - "end\n" + // - "class Float\n" + // - " def +(other)\n" + // - " self - other\n" + // - " end\n" + // - "end\n" + // - "puts add(14, 2)\n" + // - "puts add(14.5, 2.25)"); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/ShortcutTests.java --- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/ShortcutTests.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.test.language; - -import org.junit.*; - -import com.oracle.truffle.ruby.test.*; - -/** - * Test shortcut expressions (syntactic sugar) such as {@code +=} and {@code |=}. - */ -public class ShortcutTests extends RubyTests { - - @Test - public void testShortcutAddAssign() { - assertPrints("2\n", "x = 1; x += 1; puts x"); - } - - @Test - public void testShortcutSubAssign() { - assertPrints("0\n", "x = 1; x -= 1; puts x"); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/SpecialVariableTests.java --- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/SpecialVariableTests.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.test.language; - -import org.junit.*; - -import com.oracle.truffle.ruby.test.*; - -/** - * Test variables with special semantics, such as the 'global variables', {@code $_}, {@code $~} - * etc. - */ -public class SpecialVariableTests extends RubyTests { - - @Test - public void testGetsResult() { - assertPrintsWithInput("test\n", "gets; puts $_", "test\n"); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/UntilTests.java --- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/UntilTests.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.test.language; - -import org.junit.*; - -import com.oracle.truffle.ruby.test.*; - -/** - * Test {@code until} expressions. - */ -public class UntilTests extends RubyTests { - - @Test - public void testSimpleWhile() { - assertPrints("0\n", "x = 10; until x == 0; x -= 1; end; puts x"); - assertPrints("10\n", "x = 0; until x == 10; x += 1; end; puts x"); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/WhileTests.java --- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/language/WhileTests.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.test.language; - -import org.junit.*; - -import com.oracle.truffle.ruby.test.*; - -/** - * Test {@code while} expressions. - */ -public class WhileTests extends RubyTests { - - @Test - public void testSimpleWhile() { - assertPrints("0\n", "x = 10; while x > 0; x -= 1; end; puts x"); - assertPrints("10\n", "x = 0; while x < 10; x += 1; end; puts x"); - } - - @Test - public void testBreak() { - assertPrints("1\n", "x = 0; while x < 10; x += 1; break; end; puts x"); - } - - @Test - public void testNext() { - assertPrints("10\n", "x = 0; while x < 10; x += 1; next; end; puts x"); - } - -} diff -r fde464340755 -r d2c84a0bf37a graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/runtime/ObjectLayoutTests.java --- a/graal/com.oracle.truffle.ruby.test/src/com/oracle/truffle/ruby/test/runtime/ObjectLayoutTests.java Fri Feb 28 16:35:52 2014 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,277 +0,0 @@ -/* - * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This - * code is released under a tri EPL/GPL/LGPL license. You can use it, - * redistribute it and/or modify it under the terms of the: - * - * Eclipse Public License version 1.0 - * GNU General Public License version 2 - * GNU Lesser General Public License version 2.1 - */ -package com.oracle.truffle.ruby.test.runtime; - -import org.junit.*; - -import com.oracle.truffle.ruby.runtime.*; -import com.oracle.truffle.ruby.runtime.core.*; -import com.oracle.truffle.ruby.runtime.objects.*; - -import static org.junit.Assert.*; - -/** - * Test the object layout classes. - */ -public class ObjectLayoutTests { - - @Test - public void testNewInstanceVariable() { - final RubyContext context = new RubyContext(null); - - // Create a class and an instance - - final RubyClass classA = new RubyClass(context, null, null, null, "A"); - final ObjectLayout layoutClassA = classA.getObjectLayoutForInstances(); - - final RubyBasicObject objectA = new RubyBasicObject(classA); - final ObjectLayout layoutObjectA = objectA.getObjectLayout(); - - // Add an instance variable to the instance - - objectA.setInstanceVariable("foo", 14); - - // That should have changed the layout of the class - - assertNotSame(layoutClassA, classA.getObjectLayoutForInstances()); - - // If we notify the object, it should also change the layout of that - - objectA.updateLayout(); - assertNotSame(layoutObjectA, objectA.getObjectLayout()); - - // We should be able to find that instance variable as a storage location in the class - - assertNotNull(classA.getObjectLayoutForInstances().findStorageLocation("foo")); - - // We should be able to read that value back out - - assertEquals(14, objectA.getInstanceVariable("foo")); - } - - @Test - public void testOverflowPrimitives() { - final RubyContext context = new RubyContext(null); - - // Create a class and an instance - - final RubyClass classA = new RubyClass(context, null, null, null, "A"); - final RubyBasicObject objectA = new RubyBasicObject(classA); - - // Add many more Fixnums that we have space for primitives - - final int count = 100; - - for (int n = 0; n < count; n++) { - objectA.setInstanceVariable("foo" + n, n); - } - - // We should be able to read them back out - - for (int n = 0; n < count; n++) { - assertEquals(n, objectA.getInstanceVariable("foo" + n)); - } - } - - @Test - public void testGeneralisation() { - final RubyContext context = new RubyContext(null); - - // Create a class and two instances - - final RubyClass classA = new RubyClass(context, null, null, null, "A"); - final RubyBasicObject object1 = new RubyBasicObject(classA); - final RubyBasicObject object2 = new RubyBasicObject(classA); - - // Set an instance variable to be a Fixnum in object 1 - - object1.setInstanceVariable("foo", 14); - - // We should be able to read that instance variable back, and it should still be a Fixnum - - assertEquals(14, object1.getInstanceVariable("foo")); - assertSame(Integer.class, object1.getInstanceVariable("foo").getClass()); - - // The underlying instance store should be Fixnum - - assertSame(FixnumStorageLocation.class, object1.getObjectLayout().findStorageLocation("foo").getClass()); - - /* - * The same instance variable in object 2 should be Nil. Note that this requires that we - * realise that even though the instance variable is known about in the layout of object 2, - * and we are using a primitive int to hold it, that it hasn't been set and is actually Nil. - * We don't want it to appear as 0. - */ - - assertSame(NilPlaceholder.INSTANCE, object2.getInstanceVariable("foo")); - - /* - * We should be able to set the same instance variable in object 2 to also be a Fixnum - * without changing the layout. - */ - - final ObjectLayout objectLayout2 = object2.getObjectLayout(); - object2.setInstanceVariable("foo", 2); - assertEquals(2, object2.getInstanceVariable("foo")); - assertSame(Integer.class, object2.getInstanceVariable("foo").getClass()); - assertSame(objectLayout2, object2.getObjectLayout()); - - // Set the instance variable in object 2 to be a Float - - object2.setInstanceVariable("foo", 2.25); - - // We should be able to read that instance variable back, and it should still be a Fixnum - - assertEquals(2.25, object2.getInstanceVariable("foo")); - assertSame(Double.class, object2.getInstanceVariable("foo").getClass()); - - // Object 1 should give still think the instance variable is a Fixnum - - assertEquals(14, object1.getInstanceVariable("foo")); - assertSame(Integer.class, object1.getInstanceVariable("foo").getClass()); - - // The underlying instance store in both objects should now be Object - - assertSame(ObjectStorageLocation.class, object1.getObjectLayout().findStorageLocation("foo").getClass()); - assertSame(ObjectStorageLocation.class, object2.getObjectLayout().findStorageLocation("foo").getClass()); - - } - - @Test - public void testSubclasses() { - final RubyContext context = new RubyContext(null); - - // Create two classes, A, and a subclass, B, and an instance of each - - final RubyClass classA = new RubyClass(context, null, null, null, "A"); - final RubyClass classB = new RubyClass(context, null, null, classA, "B"); - - ObjectLayout layoutClassA = classA.getObjectLayoutForInstances(); - ObjectLayout layoutClassB = classA.getObjectLayoutForInstances(); - - final RubyBasicObject objectA = new RubyBasicObject(classA); - final RubyBasicObject objectB = new RubyBasicObject(classB); - - ObjectLayout layoutObjectA = objectA.getObjectLayout(); - ObjectLayout layoutObjectB = objectB.getObjectLayout(); - - // Add an instance variable to the instance of A - - objectA.setInstanceVariable("foo", 14); - - // That should have changed the layout of both classes - - assertNotSame(layoutClassA, classA.getObjectLayoutForInstances()); - assertNotSame(layoutClassB, classB.getObjectLayoutForInstances()); - - layoutClassA = classA.getObjectLayoutForInstances(); - layoutClassB = classA.getObjectLayoutForInstances(); - - // If we notify the objects, both of them should have changed layouts - - objectA.updateLayout(); - objectB.updateLayout(); - assertNotSame(layoutObjectA, objectA.getObjectLayout()); - assertNotSame(layoutObjectB, objectB.getObjectLayout()); - - layoutObjectA = objectA.getObjectLayout(); - layoutObjectB = objectB.getObjectLayout(); - - // We should be able to find that instance variable as a storage location in both classes - - assertNotNull(classA.getObjectLayoutForInstances().findStorageLocation("foo")); - assertNotNull(classB.getObjectLayoutForInstances().findStorageLocation("foo")); - - // We should be able to read that value back out - - assertEquals(14, objectA.getInstanceVariable("foo")); - - // Add an instance variable to the instance of B - - objectB.setInstanceVariable("bar", 2); - - // This should not have changed the layout of A or the instance of A - - assertSame(layoutClassA, classA.getObjectLayoutForInstances()); - assertSame(layoutObjectA, objectA.getObjectLayout()); - - // But the layout of B and the instance of B should have changed - - assertNotSame(layoutClassB, classB.getObjectLayoutForInstances()); - - objectB.updateLayout(); - assertNotSame(layoutObjectB, objectB.getObjectLayout()); - - // We should be able to find the new instance variable in the instance of B but not A - - assertNull(classA.getObjectLayoutForInstances().findStorageLocation("bar")); - assertNotNull(classB.getObjectLayoutForInstances().findStorageLocation("bar")); - - // We should be able to read that value back out - - assertEquals(2, objectB.getInstanceVariable("bar")); - } - - @Test - public void testPerObjectInstanceVariables() { - final RubyContext context = new RubyContext(null); - - // Create a class and an instance - - final RubyClass classA = new RubyClass(context, context.getCoreLibrary().getClassClass(), null, null, "A"); - final RubyBasicObject objectA = new RubyBasicObject(classA); - - ObjectLayout layoutClassA = classA.getObjectLayoutForInstances(); - ObjectLayout layoutObjectA = objectA.getObjectLayout(); - - // Add an instance variable to the instance of A - - objectA.setInstanceVariable("foo", 2); - - // That should have changed the layout of the class and the object - - assertNotSame(layoutClassA, classA.getObjectLayoutForInstances()); - assertNotSame(layoutObjectA, objectA.getObjectLayout()); - layoutClassA = classA.getObjectLayoutForInstances(); - layoutObjectA = classA.getObjectLayout(); - - // We should be able to read the value back out - - assertEquals(2, objectA.getInstanceVariable("foo")); - - /* - * Switch object A to having a private object layout, as would be done by calls such as - * instance_variable_set. - */ - - objectA.switchToPrivateLayout(); - - // Set an instance variable on object A - - objectA.setInstanceVariable("bar", 14); - - // The layout of object A, however, should have changed - - // CS: it hasn't changed because it's still null - // assertNotSame(layoutObjectA, objectA.getObjectLayout()); - - // We should be able to read the value back out - - assertEquals(14, objectA.getInstanceVariable("bar")); - - /* - * We should also be able to read the first variable back out, even though we've switched to - * private layout since then. - */ - - assertEquals(2, objectA.getInstanceVariable("foo")); - } - -} diff -r fde464340755 -r d2c84a0bf37a mx/mx_graal.py --- a/mx/mx_graal.py Fri Feb 28 16:35:52 2014 -0800 +++ b/mx/mx_graal.py Tue Mar 04 01:08:46 2014 +0000 @@ -1466,17 +1466,6 @@ def isGraalEnabled(vm): return vm != 'original' and not vm.endswith('nograal') -def rubyShellCp(): - return mx.classpath("com.oracle.truffle.ruby.shell") - -def rubyShellClass(): - return "com.oracle.truffle.ruby.shell.Shell" - -def ruby(args): - """run a Ruby program or shell""" - vmArgs, rubyArgs = _extract_VM_args(args, useDoubleDash=True) - vm(vmArgs + ['-cp', rubyShellCp(), rubyShellClass()] + rubyArgs) - def site(args): """create a website containing javadoc and the project dependency graph""" @@ -1636,8 +1625,7 @@ 'deoptalot' : [deoptalot, '[n]'], 'longtests' : [longtests, ''], 'sl' : [sl, '[SL args|@VM options]'], - 'trufflejar' : [trufflejar, ''], - 'ruby' : [ruby, '[Ruby args|@VM options]'] + 'trufflejar' : [trufflejar, ''] } mx.add_argument('--jacoco', help='instruments com.oracle.* classes using JaCoCo', default='off', choices=['off', 'on', 'append']) diff -r fde464340755 -r d2c84a0bf37a mx/projects --- a/mx/projects Fri Feb 28 16:35:52 2014 -0800 +++ b/mx/projects Tue Mar 04 01:08:46 2014 +0000 @@ -34,48 +34,6 @@ library@OKRA_WITH_SIM@sourcePath=lib/okra-1.8-with-sim-src.jar library@OKRA_WITH_SIM@sourceUrls=http://cr.openjdk.java.net/~tdeneau/okra-1.8-with-sim-src.jar -library@JRUBYPARSER@path=lib/jrubyparser-0.5.0.jar -library@JRUBYPARSER@urls=http://repo1.maven.org/maven2/org/jruby/jrubyparser/0.5.0/jrubyparser-0.5.0.jar - -library@JLINE@path=lib/jline-2.11.jar -library@JLINE@urls=http://repo1.maven.org/maven2/jline/jline/2.11/jline-2.11.jar - -library@JRUBYSTDLIB@path=lib/jruby-stdlib-1.7.4.jar -library@JRUBYSTDLIB@urls=http://repo1.maven.org/maven2/org/jruby/jruby-stdlib/1.7.4/jruby-stdlib-1.7.4.jar - -library@JNR_POSIX@path=lib/jnr-posix-3.0.1.jar -library@JNR_POSIX@urls=http://repo1.maven.org/maven2/com/github/jnr/jnr-posix/3.0.1/jnr-posix-3.0.1.jar - -library@JNR_CONSTANTS@path=lib/jnr-constants-0.8.5.jar -library@JNR_CONSTANTS@urls=http://repo1.maven.org/maven2/com/github/jnr/jnr-constants/0.8.5/jnr-constants-0.8.5.jar - -library@JNR_FFI@path=lib/jnr-ffi-1.0.10.jar -library@JNR_FFI@urls=http://repo1.maven.org/maven2/com/github/jnr/jnr-ffi/1.0.10/jnr-ffi-1.0.10.jar - -library@JFFI@path=lib/jffi-1.2.7.jar -library@JFFI@urls=http://repo1.maven.org/maven2/com/github/jnr/jffi/1.2.7/jffi-1.2.7.jar - -library@JFFI_NATIVE@path=lib/jffi-1.2.7-native.jar -library@JFFI_NATIVE@urls=http://search.maven.org/remotecontent?filepath=com/github/jnr/jffi/1.2.7/jffi-1.2.7-native.jar - -library@JNR_X86ASM@path=lib/jnr-x86asm-1.0.2.jar -library@JNR_X86ASM@urls=http://repo1.maven.org/maven2/com/github/jnr/jnr-x86asm/1.0.2/jnr-x86asm-1.0.2.jar - -library@ASM@path=lib/asm-4.0.jar -library@ASM@urls=http://repo1.maven.org/maven2/org/ow2/asm/asm/4.0/asm-4.0.jar - -library@ASM_ANALYSIS@path=lib/asm-analysis-4.0.jar -library@ASM_ANALYSIS@urls=http://repo1.maven.org/maven2/org/ow2/asm/asm-analysis/4.0/asm-analysis-4.0.jar - -library@ASM_COMMONS@path=lib/asm-commons-4.0.jar -library@ASM_COMMONS@urls=http://repo1.maven.org/maven2/org/ow2/asm/asm-commons/4.0/asm-commons-4.0.jar - -library@ASM_TREE@path=lib/asm-tree-4.0.jar -library@ASM_TREE@urls=http://repo1.maven.org/maven2/org/ow2/asm/asm-tree/4.0/asm-tree-4.0.jar - -library@ASM_UTIL@path=lib/asm-util-4.0.jar -library@ASM_UTIL@urls=http://repo1.maven.org/maven2/org/ow2/asm/asm-util/4.0/asm-util-4.0.jar - distribution@GRAAL@path=graal.jar distribution@GRAAL@dependencies=\ com.oracle.graal.hotspot.amd64,\ @@ -741,43 +699,3 @@ project@com.oracle.graal.truffle.hotspot.amd64@javaCompliance=1.7 project@com.oracle.graal.truffle.hotspot.amd64@annotationProcessors=com.oracle.graal.service.processor project@com.oracle.graal.truffle.hotspot.amd64@workingSets=Graal,Truffle - -# truffle.ruby.runtime -project@com.oracle.truffle.ruby.runtime@subDir=graal -project@com.oracle.truffle.ruby.runtime@sourceDirs=src -project@com.oracle.truffle.ruby.runtime@dependencies=JRUBYSTDLIB,JNR_POSIX,JNR_CONSTANTS,JNR_FFI,JFFI,JFFI_NATIVE,JNR_X86ASM,ASM,ASM_ANALYSIS,ASM_COMMONS,ASM_TREE,ASM_UTIL,com.oracle.truffle.api -project@com.oracle.truffle.ruby.runtime@javaCompliance=1.7 -project@com.oracle.truffle.ruby.runtime@workingSets=Truffle,Ruby - -# truffle.ruby.nodes -project@com.oracle.truffle.ruby.nodes@subDir=graal -project@com.oracle.truffle.ruby.nodes@sourceDirs=src -project@com.oracle.truffle.ruby.nodes@dependencies=com.oracle.truffle.ruby.runtime,com.oracle.truffle.api.dsl -project@com.oracle.truffle.ruby.nodes@checkstyle=com.oracle.truffle.ruby.runtime -project@com.oracle.truffle.ruby.nodes@javaCompliance=1.7 -project@com.oracle.truffle.ruby.nodes@annotationProcessors=com.oracle.truffle.dsl.processor -project@com.oracle.truffle.ruby.nodes@workingSets=Truffle,Ruby - -# truffle.ruby.parser -project@com.oracle.truffle.ruby.parser@subDir=graal -project@com.oracle.truffle.ruby.parser@sourceDirs=src -project@com.oracle.truffle.ruby.parser@dependencies=JRUBYPARSER,com.oracle.truffle.ruby.nodes -project@com.oracle.truffle.ruby.parser@checkstyle=com.oracle.truffle.ruby.runtime -project@com.oracle.truffle.ruby.parser@javaCompliance=1.7 -project@com.oracle.truffle.ruby.parser@workingSets=Truffle,Ruby - -# truffle.ruby.shell -project@com.oracle.truffle.ruby.shell@subDir=graal -project@com.oracle.truffle.ruby.shell@sourceDirs=src -project@com.oracle.truffle.ruby.shell@dependencies=JLINE,com.oracle.truffle.ruby.parser -project@com.oracle.truffle.ruby.shell@checkstyle=com.oracle.truffle.ruby.runtime -project@com.oracle.truffle.ruby.shell@javaCompliance=1.7 -project@com.oracle.truffle.ruby.shell@workingSets=Truffle,Ruby - -# truffle.ruby.test -project@com.oracle.truffle.ruby.test@subDir=graal -project@com.oracle.truffle.ruby.test@sourceDirs=src -project@com.oracle.truffle.ruby.test@dependencies=com.oracle.truffle.ruby.parser,JUNIT -project@com.oracle.truffle.ruby.test@checkstyle=com.oracle.truffle.ruby.runtime -project@com.oracle.truffle.ruby.test@javaCompliance=1.7 -project@com.oracle.truffle.ruby.test@workingSets=Truffle,Ruby,Test