public void setBehaveAsBlock(boolean behaveAsBlock) {
    CompilerAsserts.neverPartOfCompilation();

    this.behaveAsBlock = behaveAsBlock;

    // No need to deoptimize, as we're only doing this during clone
  }
  @TruffleBoundary
  public static void setClassVariable(
      RubyModule module, String name, Object value, RubyNode currentNode) {
    CompilerAsserts.neverPartOfCompilation();

    // Look in the current module

    if (module.getClassVariables().containsKey(name)) {
      module.setClassVariable(currentNode, name, value);
      return;
    }

    // Look in ancestors

    for (RubyModule ancestor : module.parentAncestors()) {
      if (ancestor.getClassVariables().containsKey(name)) {
        ancestor.setClassVariable(currentNode, name, value);
        return;
      }
    }

    // Not existing class variable - set in the current module

    module.setClassVariable(currentNode, name, value);
  }
  @TruffleBoundary
  public static InternalMethod lookupMethod(RubyModule module, String name) {
    CompilerAsserts.neverPartOfCompilation();

    InternalMethod method;

    // Look in the current module
    method = module.getMethods().get(name);

    if (method != null) {
      return method;
    }

    // Look in ancestors
    for (RubyModule ancestor : module.parentAncestors()) {
      method = ancestor.getMethods().get(name);

      if (method != null) {
        return method;
      }
    }

    // Nothing found

    return null;
  }
  public DynamicObject getNormalObjectSingletonClass(DynamicObject object) {
    CompilerAsserts.neverPartOfCompilation();

    if (RubyGuards.isRubyClass(object)) { // For the direct caller
      return ClassNodes.getSingletonClass(object);
    }

    if (Layouts.CLASS.getIsSingleton(Layouts.BASIC_OBJECT.getMetaClass(object))) {
      return Layouts.BASIC_OBJECT.getMetaClass(object);
    }

    CompilerDirectives.transferToInterpreter();
    final DynamicObject logicalClass = BasicObjectNodes.getLogicalClass(object);

    DynamicObject attached = null;
    if (RubyGuards.isRubyModule(object)) {
      attached = object;
    }

    final String name =
        String.format(
            "#<Class:#<%s:0x%x>>",
            Layouts.MODULE.getFields(logicalClass).getName(),
            BasicObjectNodes.verySlowGetObjectID(object));
    final DynamicObject singletonClass =
        ClassNodes.createSingletonClassOfObject(getContext(), logicalClass, attached, name);
    propagateFrozen(object, singletonClass);

    Layouts.BASIC_OBJECT.setMetaClass(object, singletonClass);

    return singletonClass;
  }
Beispiel #5
0
  public boolean isVisibleTo(RubyContext context, LexicalScope lexicalScope, RubyModule module) {
    CompilerAsserts.neverPartOfCompilation();
    assert lexicalScope == null || lexicalScope.getLiveModule() == module;

    if (!isPrivate) {
      return true;
    }

    // Look in lexical scope
    if (lexicalScope != null) {
      while (lexicalScope != context.getRootLexicalScope()) {
        if (lexicalScope.getLiveModule() == declaringModule) {
          return true;
        }
        lexicalScope = lexicalScope.getParent();
      }
    }

    // Look in ancestors
    if (module instanceof RubyClass) {
      for (RubyModule included : module.parentAncestors()) {
        if (included == declaringModule) {
          return true;
        }
      }
    }

    // Allow Object constants if looking with lexical scope.
    if (lexicalScope != null && context.getCoreLibrary().getObjectClass() == declaringModule) {
      return true;
    }

    return false;
  }
  @TruffleBoundary
  public static Object lookupClassVariable(RubyModule module, String name) {
    CompilerAsserts.neverPartOfCompilation();

    Object value;

    // Look in the current module
    value = module.getClassVariables().get(name);

    if (value != null) {
      return value;
    }

    // Look in ancestors
    for (RubyModule ancestor : module.parentAncestors()) {
      value = ancestor.getClassVariables().get(name);

      if (value != null) {
        return value;
      }
    }

    // Nothing found

    return null;
  }
Beispiel #7
0
  public static DynamicObject createOneSingletonClass(DynamicObject rubyClass) {
    CompilerAsserts.neverPartOfCompilation();

    if (Layouts.CLASS.getIsSingleton(Layouts.BASIC_OBJECT.getMetaClass(rubyClass))) {
      return Layouts.BASIC_OBJECT.getMetaClass(rubyClass);
    }

    final DynamicObject singletonSuperclass;
    if (getSuperClass(rubyClass) == null) {
      singletonSuperclass = Layouts.BASIC_OBJECT.getLogicalClass(rubyClass);
    } else {
      singletonSuperclass = createOneSingletonClass(getSuperClass(rubyClass));
    }

    String name = String.format("#<Class:%s>", Layouts.MODULE.getFields(rubyClass).getName());
    Layouts.BASIC_OBJECT.setMetaClass(
        rubyClass,
        ClassNodes.createRubyClass(
            Layouts.MODULE.getFields(Layouts.BASIC_OBJECT.getLogicalClass(rubyClass)).getContext(),
            Layouts.BASIC_OBJECT.getLogicalClass(rubyClass),
            null,
            singletonSuperclass,
            name,
            true,
            rubyClass));

    return Layouts.BASIC_OBJECT.getMetaClass(rubyClass);
  }
  @ExplodeLoop
  @Override
  public final Object execute(VirtualFrame frame) {
    final Object self = RubyArguments.getSelf(frame.getArguments());

    // 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 RubyNilClass) {
        blockObject = null;
      } else {
        blockObject = (RubyProc) blockTempObject;
      }
    } else {
      blockObject = null;
    }

    // Check we have a method and the module is unmodified

    if (!guard(frame, self)) {
      CompilerDirectives.transferToInterpreterAndInvalidate();
      lookup(frame);
    }

    // Call the method

    if (isSplatted) {
      // TODO(CS): need something better to splat the arguments array
      notDesignedForCompilation();
      final RubyArray argumentsArray = (RubyArray) argumentsObjects[0];
      return callNode.call(
          frame,
          RubyArguments.pack(
              superMethod,
              superMethod.getDeclarationFrame(),
              self,
              blockObject,
              argumentsArray.slowToArray()));
    } else {
      return callNode.call(
          frame,
          RubyArguments.pack(
              superMethod, superMethod.getDeclarationFrame(), self, blockObject, argumentsObjects));
    }
  }
 private void updateProfiledArgumentTypes(Object[] args, Class<?>[] types) {
   CompilerAsserts.neverPartOfCompilation();
   profiledArgumentTypesAssumption.invalidate();
   for (int j = 0; j < types.length; j++) {
     types[j] = joinTypes(types[j], classOf(args[j]));
   }
   profiledArgumentTypesAssumption =
       Truffle.getRuntime().createAssumption("Profiled Argument Types");
 }
 private Counter createCounter(SourceSection section) {
   CompilerAsserts.neverPartOfCompilation();
   // For a production profiler you might want to differentiate between sources.
   Counter counter = counters.get(section);
   if (counter == null) {
     counter = new Counter();
     counters.put(section, counter);
   }
   return counter;
 }
 private void reportLoopCount(final long count) {
   CompilerAsserts.neverPartOfCompilation("reportLoopCount");
   Node current = getParent();
   while (current != null && !(current instanceof RootNode)) {
     current = current.getParent();
   }
   if (current != null) {
     ((Invokable) current).propagateLoopCountThroughoutLexicalScope(count);
   }
 }
Beispiel #12
0
  public static DynamicObject getSuperClass(DynamicObject rubyClass) {
    CompilerAsserts.neverPartOfCompilation();

    for (DynamicObject ancestor : Layouts.MODULE.getFields(rubyClass).parentAncestors()) {
      if (RubyGuards.isRubyClass(ancestor)) {
        return ancestor;
      }
    }

    return null;
  }
Beispiel #13
0
  public void enterThread() {
    CompilerAsserts.neverPartOfCompilation();

    lock.lock();
    try {
      phaser.register();
      runningThreads.add(Thread.currentThread());
    } finally {
      lock.unlock();
    }
  }
 @Override
 public String toString() {
   CompilerAsserts.neverPartOfCompilation();
   String superString = rootNode.toString();
   if (isValid()) {
     superString += " <opt>";
   }
   if (sourceCallTarget != null) {
     superString += " <split-" + cloneIndex + "-" + argumentStamp.toStringShort() + ">";
   }
   return superString;
 }
Beispiel #15
0
  public static SInvokable constructPrimitive(
      final SSymbol signature,
      final NodeFactory<? extends ExpressionNode> nodeFactory,
      final Universe universe,
      final SClass holder) {
    CompilerAsserts.neverPartOfCompilation();
    int numArgs = signature.getNumberOfSignatureArguments();

    MethodGenerationContext mgen = new MethodGenerationContext(null);
    ExpressionNode[] args = new ExpressionNode[numArgs];
    for (int i = 0; i < numArgs; i++) {
      args[i] = new LocalArgumentReadNode(i, null);
    }

    ExpressionNode primNode;
    switch (numArgs) {
      case 1:
        primNode = nodeFactory.createNode(args[0]);
        break;
      case 2:
        // HACK for node class where we use `executeWith`
        if (nodeFactory == PutAllNodeFactory.getInstance()) {
          primNode = nodeFactory.createNode(args[0], args[1], LengthPrimFactory.create(null));
        } else {
          primNode = nodeFactory.createNode(args[0], args[1]);
        }
        break;
      case 3:
        // HACK for node class where we use `executeWith`
        if (nodeFactory == InvokeOnPrimFactory.getInstance()) {
          primNode =
              nodeFactory.createNode(
                  args[0], args[1], args[2], ToArgumentsArrayNodeGen.create(null, null));
        } else {
          primNode = nodeFactory.createNode(args[0], args[1], args[2]);
        }
        break;
      case 4:
        primNode = nodeFactory.createNode(args[0], args[1], args[2], args[3]);
        break;
      default:
        throw new RuntimeException("Not supported by SOM.");
    }

    Primitive primMethodNode =
        new Primitive(
            primNode,
            mgen.getCurrentLexicalScope().getFrameDescriptor(),
            (ExpressionNode) primNode.deepCopy());
    SInvokable prim = Universe.newMethod(signature, primMethodNode, true, new SMethod[0]);
    return prim;
  }
Beispiel #16
0
  public static SInvokable constructEmptyPrimitive(final SSymbol signature) {
    CompilerAsserts.neverPartOfCompilation();
    MethodGenerationContext mgen = new MethodGenerationContext(null);

    ExpressionNode primNode = EmptyPrim.create(new LocalArgumentReadNode(0, null));
    Primitive primMethodNode =
        new Primitive(
            primNode,
            mgen.getCurrentLexicalScope().getFrameDescriptor(),
            (ExpressionNode) primNode.deepCopy());
    SInvokable prim = Universe.newMethod(signature, primMethodNode, true, new SMethod[0]);
    return prim;
  }
  private void initializeProfiledArgumentTypes(Object[] args) {
    CompilerAsserts.neverPartOfCompilation();
    profiledArgumentTypesAssumption =
        Truffle.getRuntime().createAssumption("Profiled Argument Types");
    if (TruffleArgumentTypeSpeculation.getValue()) {
      Class<?>[] result = new Class<?>[args.length];
      for (int i = 0; i < args.length; i++) {
        result[i] = classOf(args[i]);
      }

      profiledArgumentTypes = result;
    }
  }
Beispiel #18
0
 protected static LLVMExpressionNode[] prepareForNative(LLVMExpressionNode[] originalArgs) {
   CompilerAsserts.neverPartOfCompilation();
   LLVMExpressionNode[] newNodes = new LLVMExpressionNode[originalArgs.length];
   for (int i = 0; i < newNodes.length; i++) {
     if (originalArgs[i] instanceof LLVMAddressNode) {
       newNodes[i] = LLVMAddressToI64NodeGen.create((LLVMAddressNode) originalArgs[i]);
     } else if (originalArgs[i] instanceof LLVM80BitFloatNode) {
       newNodes[i] = LLVM80BitArgConvertNodeGen.create((LLVM80BitFloatNode) originalArgs[i]);
       throw new AssertionError("foreign function interface does not support 80 bit floats yet");
     } else {
       newNodes[i] = originalArgs[i];
     }
   }
   return newNodes;
 }
  @Override
  public boolean nodeReplaced(Node oldNode, Node newNode, CharSequence reason) {
    CompilerAsserts.neverPartOfCompilation();
    if (isValid()) {
      invalidate(newNode, reason);
    }
    /* Notify compiled method that have inlined this call target that the tree changed. */
    nodeRewritingAssumption.invalidate();

    compilationProfile.reportNodeReplaced();
    if (cancelInstalledTask(newNode, reason)) {
      compilationProfile.reportInvalidated();
    }
    return false;
  }
  @Specialization(guards = "guardName")
  public Object dispatch(
      VirtualFrame frame,
      RubyNilClass methodReceiverObject,
      LexicalScope lexicalScope,
      RubySymbol receiverObject,
      Object methodName,
      Object blockObject,
      Object argumentsObjects,
      Dispatch.DispatchAction dispatchAction) {
    CompilerAsserts.compilationConstant(dispatchAction);

    // Check the class has not been modified

    try {
      unmodifiedAssumption.check();
    } catch (InvalidAssumptionException e) {
      return resetAndDispatch(
          frame,
          methodReceiverObject,
          lexicalScope,
          receiverObject,
          methodName,
          CompilerDirectives.unsafeCast(blockObject, RubyProc.class, true, false),
          argumentsObjects,
          dispatchAction,
          "class modified");
    }

    if (dispatchAction == Dispatch.DispatchAction.CALL_METHOD) {
      return callNode.call(
          frame,
          RubyArguments.pack(
              method,
              method.getDeclarationFrame(),
              receiverObject,
              CompilerDirectives.unsafeCast(blockObject, RubyProc.class, true, false),
              CompilerDirectives.unsafeCast(argumentsObjects, Object[].class, true)));
    } else if (dispatchAction == Dispatch.DispatchAction.RESPOND_TO_METHOD) {
      return true;
    } else if (dispatchAction == Dispatch.DispatchAction.READ_CONSTANT) {
      return value;
    } else {
      throw new UnsupportedOperationException();
    }
  }
Beispiel #21
0
  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.fromObjects(getContext().getCoreLibrary().getArrayClass(), executedValues);
  }
Beispiel #22
0
  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;
  }
  @TruffleBoundary
  public static Map<String, Object> getAllClassVariables(RubyModule module) {
    CompilerAsserts.neverPartOfCompilation();

    final Map<String, Object> classVariables = new HashMap<>();

    // Look in the current module
    classVariables.putAll(module.getClassVariables());

    // Look in ancestors
    for (RubyModule ancestor : module.parentAncestors()) {
      for (Map.Entry<String, Object> classVariable : ancestor.getClassVariables().entrySet()) {
        if (!classVariables.containsKey(classVariable.getKey())) {
          classVariables.put(classVariable.getKey(), classVariable.getValue());
        }
      }
    }

    return classVariables;
  }
  @TruffleBoundary
  public static Map<String, InternalMethod> getAllMethods(RubyModule module) {
    CompilerAsserts.neverPartOfCompilation();

    final Map<String, InternalMethod> methods = new HashMap<>();

    // Look in the current module
    methods.putAll(module.getMethods());

    // Look in ancestors
    for (RubyModule ancestor : module.parentAncestors()) {
      for (Map.Entry<String, InternalMethod> method : ancestor.getMethods().entrySet()) {
        if (!methods.containsKey(method.getKey())) {
          methods.put(method.getKey(), method.getValue());
        }
      }
    }

    return methods;
  }
  @TruffleBoundary
  public static InternalMethod lookupSuperMethod(
      RubyModule declaringModule, String name, RubyClass objectMetaClass) {
    CompilerAsserts.neverPartOfCompilation();

    boolean foundDeclaringModule = false;
    for (RubyModule module : objectMetaClass.ancestors()) {
      if (module == declaringModule) {
        foundDeclaringModule = true;
      } else if (foundDeclaringModule) {
        InternalMethod method = module.getMethods().get(name);

        if (method != null) {
          return method;
        }
      }
    }
    assert foundDeclaringModule
        : "Did not find the declaring module in " + objectMetaClass.getName() + " ancestors";

    return null;
  }
Beispiel #26
0
  @ExplodeLoop
  private Object handleException(VirtualFrame frame, RaiseException exception) {
    CompilerAsserts.neverPartOfCompilation();

    notDesignedForCompilation();
    getContext()
        .getCoreLibrary()
        .getGlobalVariablesObject()
        .getOperations()
        .setInstanceVariable(
            getContext().getCoreLibrary().getGlobalVariablesObject(),
            "$!",
            exception.getRubyException());

    for (RescueNode rescue : rescueParts) {
      if (rescue.canHandle(frame, exception.getRubyException())) {
        return rescue.execute(frame);
      }
    }

    throw exception;
  }
  @TruffleBoundary
  public static Map<String, RubyConstant> getAllConstants(RubyModule module) {
    CompilerAsserts.neverPartOfCompilation();

    final Map<String, RubyConstant> constants = new HashMap<>();

    // Look in the current module
    constants.putAll(module.getConstants());

    // TODO(eregon): Look in lexical scope?

    // Look in ancestors
    for (RubyModule ancestor : module.parentAncestors()) {
      for (Map.Entry<String, RubyConstant> constant : ancestor.getConstants().entrySet()) {
        if (!constants.containsKey(constant.getKey())) {
          constants.put(constant.getKey(), constant.getValue());
        }
      }
    }

    return constants;
  }
Beispiel #28
0
 private ForeignAccess(Factory faf) {
   this.factory = faf;
   this.initThread = Thread.currentThread();
   CompilerAsserts.neverPartOfCompilation(
       "do not create a ForeignAccess object from compiled code");
 }
Beispiel #29
0
  public void leaveThread() {
    CompilerAsserts.neverPartOfCompilation();

    phaser.arriveAndDeregister();
    runningThreads.remove(Thread.currentThread());
  }
Beispiel #30
0
 protected SetDispatchNode rewrite(SetDispatchNode next) {
   CompilerAsserts.neverPartOfCompilation();
   assert this != next;
   return replace(next);
 }