public CachedBoxedSymbolDispatchNode(
      RubyContext context,
      Object cachedName,
      DispatchNode next,
      Object value,
      InternalMethod method,
      boolean indirect,
      DispatchAction dispatchAction) {
    super(context, cachedName, next, indirect, dispatchAction);

    unmodifiedAssumption = context.getCoreLibrary().getSymbolClass().getUnmodifiedAssumption();
    this.value = value;
    this.method = method;

    if (method != null) {
      if (indirect) {
        indirectCallNode = Truffle.getRuntime().createIndirectCallNode();
      } else {
        callNode = Truffle.getRuntime().createDirectCallNode(method.getCallTarget());

        if (callNode.isCallTargetCloningAllowed()
            && method.getSharedMethodInfo().shouldAlwaysSplit()) {
          insert(callNode);
          callNode.cloneCallTarget();
        }
      }
    }
  }
Ejemplo n.º 2
0
  @TruffleBoundary
  private SafepointAction step(Node currentNode, boolean isDrivingThread) {
    final DynamicObject thread = context.getThreadManager().getCurrentThread();

    // wait other threads to reach their safepoint
    phaser.arriveAndAwaitAdvance();

    if (isDrivingThread) {
      assumption = Truffle.getRuntime().createAssumption("SafepointManager");
    }

    // wait the assumption to be renewed
    phaser.arriveAndAwaitAdvance();

    // Read these while in the safepoint.
    SafepointAction deferredAction = deferred ? action : null;

    try {
      if (!deferred && thread != null && Layouts.THREAD.getStatus(thread) != Status.ABORTING) {
        action.run(thread, currentNode);
      }
    } finally {
      // wait other threads to finish their action
      phaser.arriveAndAwaitAdvance();
    }

    return deferredAction;
  }
Ejemplo n.º 3
0
 @Override
 public Object execute(
     TranslatorDriver.ParserContext parserContext,
     Object self,
     MaterializedFrame parentFrame,
     org.jruby.ast.RootNode rootNode) {
   try {
     final RubyParserResult parseResult =
         truffleContext
             .getTranslator()
             .parse(
                 truffleContext,
                 truffleContext.getSourceManager().get(rootNode.getPosition().getFile()),
                 parserContext,
                 parentFrame,
                 rootNode);
     final CallTarget callTarget =
         Truffle.getRuntime().createCallTarget(parseResult.getRootNode());
     return callTarget.call(RubyArguments.pack(parentFrame, self, null));
   } catch (ThrowException e) {
     throw new RaiseException(truffleContext.getCoreLibrary().nameErrorUncaughtThrow(e.getTag()));
   } catch (RaiseException | BreakShellException | QuitException e) {
     throw e;
   } catch (Throwable e) {
     e.printStackTrace();
     throw new RaiseException(ExceptionTranslator.translateException(truffleContext, e));
   }
 }
Ejemplo n.º 4
0
 @Override
 public TruffleMethod truffelize(DynamicMethod originalMethod, ArgsNode argsNode, Node bodyNode) {
   final MethodDefinitionNode methodDefinitionNode =
       truffleContext.getTranslator().parse(truffleContext, null, argsNode, bodyNode);
   return new TruffleMethod(
       originalMethod,
       Truffle.getRuntime().createCallTarget(methodDefinitionNode.getMethodRootNode()));
 }
Ejemplo n.º 5
0
    @Specialization
    public RubyString fullTree() {
      notDesignedForCompilation();

      return getContext()
          .makeString(
              NodeUtil.printTreeToString(
                  Truffle.getRuntime().getCallerFrame().getCallNode().getRootNode()));
    }
Ejemplo n.º 6
0
 @Test
 public void test() {
   TruffleRuntime runtime = Truffle.getRuntime();
   TestRootNode rootNode =
       new TestRootNode(new TestArgumentNode[] {new TestArgumentNode(0), new TestArgumentNode(1)});
   CallTarget target = runtime.createCallTarget(rootNode);
   Object result = target.call(new TestArguments(20, 22));
   Assert.assertEquals(42, result);
 }
Ejemplo n.º 7
0
 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");
 }
  public CachedBoxedSymbolDispatchNode(
      RubyContext context, Object cachedName, DispatchNode next, Object value, RubyMethod method) {
    super(context, cachedName, next);
    unmodifiedAssumption = context.getCoreLibrary().getSymbolClass().getUnmodifiedAssumption();
    this.value = value;
    this.method = method;

    if (method != null) {
      callNode = Truffle.getRuntime().createDirectCallNode(method.getCallTarget());
    }
  }
Ejemplo n.º 9
0
 public OpenModuleNode(
     RubyContext context,
     SourceSection sourceSection,
     RubyNode definingModule,
     MethodDefinitionNode definitionMethod,
     LexicalScope lexicalScope) {
   super(context, sourceSection);
   this.definingModule = definingModule;
   this.definitionMethod = definitionMethod;
   this.lexicalScope = lexicalScope;
   callModuleDefinitionNode = Truffle.getRuntime().createIndirectCallNode();
 }
Ejemplo n.º 10
0
  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;
    }
  }
Ejemplo n.º 11
0
  @Override
  public void enter(Node node, VirtualFrame frame) {
    try {
      traceAssumption.check();
    } catch (InvalidAssumptionException e) {

      traceAssumption = context.getTraceManager().getTraceAssumption();
      traceFunc = context.getTraceManager().getTraceFunc();

      if (traceFunc != null) {
        callNode = insert(Truffle.getRuntime().createDirectCallNode(traceFunc.getCallTarget()));
      } else {
        callNode = null;
      }
    }

    if (traceFunc != null) {
      if (!context.getTraceManager().isInTraceFunc()) {
        context.getTraceManager().setInTraceFunc(true);

        final Object[] args =
            new Object[] {
              event,
              file,
              line,
              NilPlaceholder.INSTANCE,
              new RubyBinding(
                  context.getCoreLibrary().getBindingClass(),
                  RubyArguments.getSelf(frame.getArguments()),
                  frame.materialize()),
              NilPlaceholder.INSTANCE
            };

        try {
          callNode.call(
              frame,
              RubyArguments.pack(
                  traceFunc,
                  traceFunc.getDeclarationFrame(),
                  traceFunc.getSelfCapturedInScope(),
                  traceFunc.getBlockCapturedInScope(),
                  args));
        } finally {
          context.getTraceManager().setInTraceFunc(false);
        }
      }
    }
  }
Ejemplo n.º 12
0
 private boolean lazyUpdatedImpl(VirtualFrame frame) {
   Node nextChain = instrumenter.installBindings(ProbeNode.this);
   if (nextChain == null) {
     // chain is null -> remove wrapper;
     // Note: never set child nodes to null, can cause races
     InstrumentationHandler.removeWrapper(ProbeNode.this);
     return false;
   }
   EventChainNode oldChain = this.chain;
   if (oldChain != null) {
     oldChain.onDispose(context, frame);
   }
   this.chain = (EventChainNode) insert(nextChain);
   this.version = Truffle.getRuntime().createAssumption("Instrumentations unchanged");
   return true;
 }
Ejemplo n.º 13
0
  public CachedYieldDispatchNode(RubyContext context, RubyProc block, YieldDispatchNode next) {
    super(context);

    callNode = Truffle.getRuntime().createDirectCallNode(block.getCallTargetForBlocks());
    insert(callNode);

    if (INLINER_ALWAYS_CLONE_YIELD && callNode.isCallTargetCloningAllowed()) {
      callNode.cloneCallTarget();
    }

    if (INLINER_ALWAYS_INLINE_YIELD && callNode.isInlinable()) {
      callNode.forceInlining();
    }

    this.next = next;
  }
Ejemplo n.º 14
0
  public CachedSingletonDispatchNode(
      RubyContext context,
      Object cachedName,
      DispatchNode next,
      DynamicObject expectedReceiver,
      DynamicObject expectedClass,
      InternalMethod method,
      DispatchAction dispatchAction) {
    super(context, cachedName, next, dispatchAction);

    this.expectedReceiver = expectedReceiver;
    this.unmodifiedAssumption = Layouts.MODULE.getFields(expectedClass).getUnmodifiedAssumption();
    this.next = next;
    this.method = method;
    this.callNode = Truffle.getRuntime().createDirectCallNode(method.getCallTarget());
    applySplittingInliningStrategy(callNode, method);
  }
Ejemplo n.º 15
0
 public void profileReturnType(Object result) {
   Assumption returnTypeAssumption = profiledReturnTypeAssumption;
   if (returnTypeAssumption == null) {
     if (TruffleReturnTypeSpeculation.getValue()) {
       CompilerDirectives.transferToInterpreterAndInvalidate();
       profiledReturnType = (result == null ? null : result.getClass());
       profiledReturnTypeAssumption =
           Truffle.getRuntime().createAssumption("Profiled Return Type");
     }
   } else if (profiledReturnType != null) {
     if (result == null || profiledReturnType != result.getClass()) {
       CompilerDirectives.transferToInterpreterAndInvalidate();
       profiledReturnType = null;
       returnTypeAssumption.invalidate();
     }
   }
 }
/**
 * Slow-path code for a call, used when the polymorphic inline cache exceeded its maximum size. Such
 * calls are not optimized any further, e.g., no method inlining is performed.
 */
final class LlvmGenericDispatchNode extends LlvmAbstractDispatchNode {

  /**
   * {@link IndirectCallNode} is part of the Truffle API and handles all the steps necessary for
   * calling a megamorphic call-site. The Graal specific version of this node performs additional
   * optimizations for the fast access of the SimpleLanguage stack trace.
   */
  @Child private IndirectCallNode callNode = Truffle.getRuntime().createIndirectCallNode();

  @Override
  protected Object executeDispatch(VirtualFrame frame, LlvmFunction function, Object[] arguments) {
    /*
     * Llvm has a quite simple call lookup: just ask the function for the current call target,
     * and call it.
     */
    return callNode.call(frame, function.getCallTarget(), arguments);
  }
}
Ejemplo n.º 17
0
  public MethodDefinitionNode compileMethodNode(
      SourceSection sourceSection,
      String methodName,
      org.jruby.ast.Node bodyNode,
      SharedMethodInfo sharedMethodInfo) {
    final RubyNode body = compileMethodBody(sourceSection, methodName, bodyNode, sharedMethodInfo);
    final RubyRootNode rootNode =
        new RubyRootNode(
            context,
            considerExtendingMethodToCoverEnd(body.getSourceSection()),
            environment.getFrameDescriptor(),
            environment.getSharedMethodInfo(),
            body,
            environment.needsDeclarationFrame());

    final CallTarget callTarget = Truffle.getRuntime().createCallTarget(rootNode);
    return new MethodDefinitionNode(
        context, sourceSection, methodName, environment.getSharedMethodInfo(), callTarget);
  }
Ejemplo n.º 18
0
  @Override
  public void init() {
    if (RubyContext.PRINT_RUNTIME) {
      runtime
          .getInstanceConfig()
          .getError()
          .println("jruby: using " + Truffle.getRuntime().getName());
    }

    // Bring in core method nodes

    CoreMethodNodeManager.addStandardMethods(truffleContext.getCoreLibrary().getObjectClass());

    // Give the core library manager a chance to tweak some of those methods

    truffleContext.getCoreLibrary().initializeAfterMethodsAdded();

    // Set program arguments

    for (IRubyObject arg :
        ((org.jruby.RubyArray) runtime.getObject().getConstant("ARGV")).toJavaArray()) {
      assert arg != null;

      truffleContext.getCoreLibrary().getArgv().slowPush(truffleContext.makeString(arg.toString()));
    }

    // Set the load path

    final RubyArray loadPath =
        (RubyArray)
            truffleContext.getCoreLibrary().getGlobalVariablesObject().getInstanceVariable("$:");

    for (IRubyObject path :
        ((org.jruby.RubyArray) runtime.getLoadService().getLoadPath()).toJavaArray()) {
      loadPath.slowPush(truffleContext.makeString(path.toString()));
    }

    // Hook

    if (truffleContext.getHooks() != null) {
      truffleContext.getHooks().afterInit(truffleContext);
    }
  }
Ejemplo n.º 19
0
 public static PGenerator create(
     String name,
     RootCallTarget callTarget,
     FrameDescriptor frameDescriptor,
     MaterializedFrame declarationFrame,
     Object[] arguments,
     int numOfActiveFlags,
     int numOfGeneratorBlockNode,
     int numOfGeneratorForNode) {
   /** Setting up the persistent frame in {@link #arguments}. */
   GeneratorControlData generatorArgs =
       new GeneratorControlData(numOfActiveFlags, numOfGeneratorBlockNode, numOfGeneratorForNode);
   MaterializedFrame generatorFrame =
       Truffle.getRuntime().createMaterializedFrame(PArguments.create(), frameDescriptor);
   PArguments.setDeclarationFrame(arguments, declarationFrame);
   PArguments.setGeneratorFrame(arguments, generatorFrame);
   PArguments.setControlData(arguments, generatorArgs);
   return new PGenerator(name, callTarget, frameDescriptor, arguments);
 }
Ejemplo n.º 20
0
  public CallTarget compile(String format) {
    if (format.length() > context.getOptions().PACK_RECOVER_LOOP_MIN) {
      format = LoopRecovery.recoverLoop(format);
    }

    final SimpleUnpackTreeBuilder builder = new SimpleUnpackTreeBuilder(context, currentNode);

    builder.enterSequence();

    final SimplePackParser parser =
        new SimplePackParser(builder, format.getBytes(StandardCharsets.US_ASCII));
    parser.parse();

    builder.exitSequence();

    return Truffle.getRuntime()
        .createCallTarget(
            new UnpackRootNode(
                context, currentNode.getEncapsulatingSourceSection(), builder.getNode()));
  }
Ejemplo n.º 21
0
  public Status run(String[] args) {
    try {
      if (Options.TRUFFLE_PRINT_RUNTIME.load()) {
        config.getError().println("jruby: using " + Truffle.getRuntime().getName());
      }

      config.processArguments(args);
      return internalRun();
    } catch (MainExitException mee) {
      return handleMainExit(mee);
    } catch (OutOfMemoryError oome) {
      return handleOutOfMemory(oome);
    } catch (StackOverflowError soe) {
      return handleStackOverflow(soe);
    } catch (UnsupportedClassVersionError ucve) {
      return handleUnsupportedClassVersion(ucve);
    } catch (ThreadKill kill) {
      return new Status();
    }
  }
Ejemplo n.º 22
0
    public static CallTarget getIndirectCallTarget(
        LLVMContext context, LLVMFunction function, LLVMExpressionNode[] args) {
      CallTarget callTarget = context.getFunction(function);
      if (callTarget == null) {
        final NativeFunctionHandle nativeHandle = context.getNativeHandle(function, args);
        if (nativeHandle == null) {
          throw new IllegalStateException("could not find function " + function.getName());
        } else {
          return Truffle.getRuntime()
              .createCallTarget(
                  new RootNode(LLVMLanguage.class, null, null) {

                    @Override
                    public Object execute(VirtualFrame frame) {
                      return nativeHandle.call(frame.getArguments());
                    }
                  });
        }
      } else {
        return callTarget;
      }
    }
Ejemplo n.º 23
0
public class SafepointManager {

  private final RubyContext context;

  private final Set<Thread> runningThreads =
      Collections.newSetFromMap(new ConcurrentHashMap<Thread, Boolean>());

  @CompilationFinal
  private Assumption assumption = Truffle.getRuntime().createAssumption("SafepointManager");

  private final ReentrantLock lock = new ReentrantLock();

  private final Phaser phaser = new Phaser();
  private volatile SafepointAction action;
  private volatile boolean deferred;

  public SafepointManager(RubyContext context) {
    this.context = context;
  }

  public void enterThread() {
    CompilerAsserts.neverPartOfCompilation();

    lock.lock();
    try {
      phaser.register();
      runningThreads.add(Thread.currentThread());
    } finally {
      lock.unlock();
    }
  }

  public void leaveThread() {
    CompilerAsserts.neverPartOfCompilation();

    phaser.arriveAndDeregister();
    runningThreads.remove(Thread.currentThread());
  }

  public void poll(Node currentNode) {
    poll(currentNode, false);
  }

  public void pollFromBlockingCall(Node currentNode) {
    poll(currentNode, true);
  }

  private void poll(Node currentNode, boolean fromBlockingCall) {
    try {
      assumption.check();
    } catch (InvalidAssumptionException e) {
      assumptionInvalidated(currentNode, fromBlockingCall);
    }
  }

  @TruffleBoundary
  private void assumptionInvalidated(Node currentNode, boolean fromBlockingCall) {
    final DynamicObject thread = context.getThreadManager().getCurrentThread();
    final InterruptMode interruptMode = Layouts.THREAD.getInterruptMode(thread);

    final boolean interruptible =
        (interruptMode == InterruptMode.IMMEDIATE)
            || (fromBlockingCall && interruptMode == InterruptMode.ON_BLOCKING);

    if (!interruptible) {
      Thread.currentThread().interrupt(); // keep the interrupt flag
      return; // interrupt me later
    }

    SafepointAction deferredAction = step(currentNode, false);

    // We're now running again normally and can run deferred actions
    if (deferredAction != null) {
      deferredAction.run(thread, currentNode);
    }
  }

  @TruffleBoundary
  private SafepointAction step(Node currentNode, boolean isDrivingThread) {
    final DynamicObject thread = context.getThreadManager().getCurrentThread();

    // wait other threads to reach their safepoint
    phaser.arriveAndAwaitAdvance();

    if (isDrivingThread) {
      assumption = Truffle.getRuntime().createAssumption("SafepointManager");
    }

    // wait the assumption to be renewed
    phaser.arriveAndAwaitAdvance();

    // Read these while in the safepoint.
    SafepointAction deferredAction = deferred ? action : null;

    try {
      if (!deferred && thread != null && Layouts.THREAD.getStatus(thread) != Status.ABORTING) {
        action.run(thread, currentNode);
      }
    } finally {
      // wait other threads to finish their action
      phaser.arriveAndAwaitAdvance();
    }

    return deferredAction;
  }

  private void interruptOtherThreads() {
    Thread current = Thread.currentThread();
    for (Thread thread : runningThreads) {
      if (thread != current) {
        thread.interrupt();
      }
    }
  }

  private void pauseAllThreadsAndExecute(
      Node currentNode, boolean isRubyThread, SafepointAction action, boolean deferred) {
    this.action = action;
    this.deferred = deferred;

    /* this is a potential cause for race conditions,
     * but we need to invalidate first so the interrupted threads
     * see the invalidation in poll() in their catch(InterruptedException) clause
     * and wait on the barrier instead of retrying their blocking action. */
    assumption.invalidate();
    interruptOtherThreads();

    step(currentNode, true);
  }

  // Variants for all threads

  @TruffleBoundary
  public void pauseAllThreadsAndExecute(
      Node currentNode, boolean deferred, SafepointAction action) {
    if (lock.isHeldByCurrentThread()) {
      throw new IllegalStateException("Re-entered SafepointManager");
    }

    // Need to lock interruptibly since we are in the registered threads.
    while (!lock.tryLock()) {
      poll(currentNode);
    }

    try {
      pauseAllThreadsAndExecute(currentNode, true, action, deferred);
    } finally {
      lock.unlock();
    }

    // Run deferred actions after leaving the SafepointManager lock.
    if (deferred) {
      action.run(context.getThreadManager().getCurrentThread(), currentNode);
    }
  }

  @TruffleBoundary
  public void pauseAllThreadsAndExecuteFromNonRubyThread(boolean deferred, SafepointAction action) {
    if (lock.isHeldByCurrentThread()) {
      throw new IllegalStateException("Re-entered SafepointManager");
    }

    assert !runningThreads.contains(Thread.currentThread());

    // Just wait to grab the lock, since we are not in the registered threads.
    lock.lock();
    try {
      enterThread();
      try {
        pauseAllThreadsAndExecute(null, false, action, deferred);
      } finally {
        leaveThread();
      }
    } finally {
      lock.unlock();
    }
  }

  // Variants for a single thread

  @TruffleBoundary
  public void pauseThreadAndExecute(
      final Thread thread, Node currentNode, final SafepointAction action) {
    if (Thread.currentThread() == thread) {
      // fast path if we are already the right thread
      DynamicObject rubyThread = context.getThreadManager().getCurrentThread();
      action.run(rubyThread, currentNode);
    } else {
      pauseAllThreadsAndExecute(
          currentNode,
          false,
          new SafepointAction() {
            @Override
            public void run(DynamicObject rubyThread, Node currentNode) {
              if (Thread.currentThread() == thread) {
                action.run(rubyThread, currentNode);
              }
            }
          });
    }
  }

  @TruffleBoundary
  public void pauseThreadAndExecuteLater(
      final Thread thread, Node currentNode, final SafepointAction action) {
    if (Thread.currentThread() == thread) {
      // fast path if we are already the right thread
      DynamicObject rubyThread = context.getThreadManager().getCurrentThread();
      action.run(rubyThread, currentNode);
    } else {
      pauseAllThreadsAndExecute(
          currentNode,
          true,
          new SafepointAction() {
            @Override
            public void run(DynamicObject rubyThread, Node currentNode) {
              if (Thread.currentThread() == thread) {
                action.run(rubyThread, currentNode);
              }
            }
          });
    }
  }

  @TruffleBoundary
  public void pauseThreadAndExecuteLaterFromNonRubyThread(
      final Thread thread, final SafepointAction action) {
    pauseAllThreadsAndExecuteFromNonRubyThread(
        true,
        new SafepointAction() {
          @Override
          public void run(DynamicObject rubyThread, Node currentNode) {
            if (Thread.currentThread() == thread) {
              action.run(rubyThread, currentNode);
            }
          }
        });
  }
}
Ejemplo n.º 24
0
 protected Assumption createAssumption() {
   return Truffle.getRuntime().createAssumption();
 }
Ejemplo n.º 25
0
 public LLVMResolvedDirectCallNode(CallTarget callTarget, LLVMExpressionNode[] args) {
   this.callNode = Truffle.getRuntime().createDirectCallNode(callTarget);
   this.args = args;
 }
Ejemplo n.º 26
0
 public IntDownToDoMessageNode(final ExpressionNode orignialNode, final SBlock block) {
   super(orignialNode.getSourceSection());
   blockMethod = block.getMethod();
   valueSend = Truffle.getRuntime().createDirectCallNode(blockMethod.getCallTarget());
 }
Ejemplo n.º 27
0
 public GeneralYieldDispatchNode(RubyContext context) {
   super(context);
   callNode = Truffle.getRuntime().createIndirectCallNode();
 }
Ejemplo n.º 28
0
 GenericObjectAccessNode(Message access) {
   this.access = access;
   indirectCallNode = Truffle.getRuntime().createIndirectCallNode();
 }
Ejemplo n.º 29
0
public class RContext {

  public static final boolean DEBUG = Utils.getProperty("RConsole.debug.gui", false);
  private static boolean debuggingFormat = false;
  private static boolean usesTruffleOptimizer =
      Truffle.getRuntime().equals("Default Truffle Runtime");
  private static ManageError errorManager = new ManageError(System.err);
  private static Truffleize truffleize = new Truffleize();
  private static final int NCONNECTIONS = 128;
  private static final Connection[] connections = new Connection[NCONNECTIONS];

  static {
    Arrays.fill(connections, null);
  }

  public static boolean usesTruffleOptimizer() {
    return usesTruffleOptimizer;
  }

  public static boolean debuggingFormat() {
    return debuggingFormat;
  }

  public static boolean debuggingFormat(boolean useDebuggingFormat) {
    boolean previous = debuggingFormat;
    debuggingFormat = useDebuggingFormat;
    return previous;
  }

  public static RAny eval(ASTNode expr, boolean useDebuggingFormat) {
    debuggingFormat(useDebuggingFormat);
    return eval(expr);
    // NOTE: cannot reset to the original value of debuggingFormat here, because usually the pretty
    // printer is
    // invoked on the results afterwards by the caller of eval; the pretty printer still depends on
    // the correct
    // setting of debugging format
  }

  public static RAny eval(ASTNode expr) {
    try {
      return (RAny) truffleize.createLazyRootTree(expr).execute(null); // null means top-level
    } catch (RError e) {
      if (DEBUG) {
        e.printStackTrace();
      }
      error(e); // throws an error
    }
    throw new Error("Never reached");
  }

  public static RNode createNode(ASTNode expr) {
    return truffleize.createTree(expr);
  }

  public static RNode createRootNode(ASTNode expr, final RFunction rootEnclosingFunction) {
    return new BaseR(expr) {
      @Child RNode node = adoptChild(truffleize.createTree(ast, rootEnclosingFunction));

      @Override
      public Object execute(Frame frame) {
        return node.execute(frame);
      }
    };
  }

  public static void warning(ASTNode expr, String msg, Object... args) {
    errorManager.warning(expr, String.format(msg, args));
  }

  public static void warning(ASTNode expr, String msg) {
    errorManager.warning(expr, msg);
  }

  public static void warning(RError err) {
    errorManager.warning(err);
  }

  public static void error(ASTNode expr, String msg) {
    errorManager.error(expr, msg);
  }

  public static void error(RError err) {
    errorManager.error(err);
  }

  public static int allocateConnection(Connection connection) {
    for (int i = 0; i < NCONNECTIONS; i++) {
      if (connections[i] == null) {
        connections[i] = connection;
        return i;
      }
    }
    return -1;
  }

  /** Release a connection currently in use. */
  public static void freeConnection(int i) {
    assert Utils.check(connections[i] != null);
    connections[i] = null;
  }

  /** Return a connection or null. */
  public static Connection getConnection(int i) {
    return i >= 0 && i < NCONNECTIONS ? connections[i] : null;
  }

  // note: GNUR currently means not only the GNU-R library, but also some other native code, under
  // licenses compatible with GPL
  private static int hasGNUR = -1;

  public static boolean hasGNUR() {
    if (hasGNUR == -1) {
      try {
        System.loadLibrary("gnurglue");
        hasGNUR = 1;
      } catch (Throwable t) {
        hasGNUR = 0;
      }
    }
    return hasGNUR == 1;
  }

  public static ASTNode parseFile(ANTLRStringStream inputStream) {
    CommonTokenStream tokens = new CommonTokenStream();
    RLexer lexer = new RLexer(inputStream);
    tokens.setTokenSource(lexer);
    RParser parser = new RParser(tokens);

    try {
      return parser.script();
    } catch (RecognitionException e) {
      Console.parseError(parser, e);
      return null;
    }
  }
}
Ejemplo n.º 30
0
 public GeneralDispatchNode(RubyContext context, String name) {
   super(context);
   assert name != null;
   this.name = name;
   callNode = Truffle.getRuntime().createIndirectCallNode();
 }