package som.interpreter;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.frame.Frame;

public final class SArguments {

  private static final int RCVR_IDX = 0;

  private static Object[] args(final Frame frame) {
    return CompilerDirectives.unsafeCast(frame.getArguments(), Object[].class, true, true);
  }

  public static Object arg(final Frame frame, final int index) {
    return CompilerDirectives.unsafeCast(args(frame)[index], Object.class, true, true);
  }

  public static Object rcvr(final Frame frame) {
    return arg(frame, RCVR_IDX);
  }

  /**
   * Create a properly encoded SArguments array to be passed via Truffle's API
   * from a receiver object that is separate from the actual arguments.
   */
  public static Object[] createSArgumentsArrayFrom(final Object receiver, final Object[] argsArray) {
    // below, we have a lot of magic numbers and implicit positioning,
    // which are all based on this assumption
    assert RCVR_IDX == 0;

    if (argsArray == null) {
      return new Object[] {receiver};
    }

    Object[] arguments = new Object[argsArray.length + 1];
    arguments[RCVR_IDX] = receiver;

    System.arraycopy(argsArray, 0, arguments, 1, argsArray.length);
    return arguments;
  }

  /**
   * Create a new array from an SArguments array that contains only the true
   * arguments and excludes the receiver. This is used for instance for
   * #doesNotUnderstand (#dnu)
   */
  @ExplodeLoop
  public static Object[] getArgumentsWithoutReceiver(final Object[] arguments) {
    // the code and magic numbers below are based on the following assumption
    assert RCVR_IDX == 0;
//    return Arrays.copyOfRange(arguments, 1, arguments.length);
    Object[] argsArr = new Object[arguments.length - 1];
    for (int i = 1; i < arguments.length; i++) {
      argsArr[i - 1] = arguments[i];
    }
    return argsArr;
  }
}

@@ -1016,16 +1016,41 @@
  == null
+ %7C%7C argsArray.length == 0
 ) %7B%0A    
@@ -1477,23 +1477,8 @@
  */%0A
-  @ExplodeLoop%0A
   pu
@@ -1662,73 +1662,8 @@
  0;%0A
-//    return Arrays.copyOfRange(arguments, 1, arguments.length);%0A
     
@@ -1723,49 +1723,31 @@
     
-for (int i = 1; i %3C arguments
+if (argsArr
 .length
-; i++
+ == 0
 ) %7B%0A
@@ -1756,44 +1756,95 @@
     
-argsArr%5Bi - 1%5D = arguments%5Bi%5D;%0A    %7D
+return argsArr;%0A    %7D%0A    System.arraycopy(arguments, 1, argsArr, 0, arguments.length);
 %0A   

Make special cases explicit and rely on arraycopy