package som.vmobjects;

import som.interpreter.SArguments;
import som.interpreter.Types;
import som.vm.Universe;

import com.oracle.truffle.api.CompilerAsserts;


public abstract class SAbstractObject {

  public abstract SClass getSOMClass();

  @Override
  public String toString() {
    return "a " + getSOMClass().getName().getString();
  }

  public static final Object send(
      final String selectorString,
      final Object[] arguments) {
    CompilerAsserts.neverPartOfCompilation("SAbstractObject.send()");
    SSymbol selector = Universe.current().symbolFor(selectorString);

    // Lookup the invokable
    SInvokable invokable = Types.getClassOf(arguments[0]).lookupInvokable(selector);

    return invokable.invoke(arguments);
  }

  public static final Object sendDoesNotUnderstand(final SSymbol selector,
      final Object[] arguments) {
    CompilerAsserts.neverPartOfCompilation("SAbstractObject.sendDNU()");
    assert arguments != null;

    // Allocate an array to hold the arguments, without receiver
    Object[] argumentsArray = SArguments.getArgumentsWithoutReceiver(arguments);
    Object[] args = new Object[] {arguments[0], selector, argumentsArray};
    return send("doesNotUnderstand:arguments:", args);
  }

  public static final Object sendUnknownGlobal(final Object receiver,
      final SSymbol globalName) {
    Object[] arguments = {receiver, globalName};
    return send("unknownGlobal:", arguments);
  }

  public static final Object sendEscapedBlock(final Object receiver,
      final SBlock block) {
    Object[] arguments = {receiver, block};
    return send("escapedBlock:", arguments);
  }

}

@@ -287,35 +287,177 @@
     
-return %22a %22 + getSOMClass()
+CompilerAsserts.neverPartOfCompilation();%0A    SClass clazz = getSOMClass();%0A    if (clazz == null) %7B%0A      return %22an Object(clazz==null)%22;%0A    %7D%0A    return %22a %22 + clazz
 .get

Make sure SAbstractObject is never compiled