Java源码示例:com.oracle.truffle.api.RootCallTarget

示例1
@TruffleBoundary
public final RootCallTarget getResumptionCallTarget(final ContextObject context) {
    if (resumptionCallTarget == null) {
        CompilerDirectives.transferToInterpreterAndInvalidate();
        resumptionCallTarget = Truffle.getRuntime().createCallTarget(ResumeContextRootNode.create(SqueakLanguage.getContext().getLanguage(), context));
    } else {
        final ResumeContextRootNode resumeNode = (ResumeContextRootNode) resumptionCallTarget.getRootNode();
        if (resumeNode.getActiveContext() != context) {
            /**
             * This is a trick: we set the activeContext of the {@link ResumeContextRootNode} to
             * the given context to be able to reuse the call target.
             */
            resumeNode.setActiveContext(context);
        }
    }
    return resumptionCallTarget;
}
 
示例2
public static Map<String, RootCallTarget> parseHashemiLang(HashemLanguage language, Source source) {
    HashemLanguageLexer lexer = new HashemLanguageLexer(CharStreams.fromString(source.getCharacters().toString()));
    HashemLanguageParser parser = new HashemLanguageParser(new CommonTokenStream(lexer));
    lexer.removeErrorListeners();
    parser.removeErrorListeners();
    BailoutErrorListener listener = new BailoutErrorListener(source);
    lexer.addErrorListener(listener);
    parser.addErrorListener(listener);
    parser.factory = new HashemNodeFactory(language, source);
    parser.source = source;
    parser.hashemlanguage();
    return parser.factory.getAllFunctions();
}
 
示例3
@TruffleBoundary
private static String createStackTrace() {
    final StringBuilder str = new StringBuilder();

    Truffle.getRuntime().iterateFrames(new FrameInstanceVisitor<Integer>() {
        private int skip = 1; // skip stack trace builtin

        @Override
        public Integer visitFrame(FrameInstance frameInstance) {
            if (skip > 0) {
                skip--;
                return null;
            }
            CallTarget callTarget = frameInstance.getCallTarget();
            Frame frame = frameInstance.getFrame(FrameAccess.READ_ONLY);
            RootNode rn = ((RootCallTarget) callTarget).getRootNode();
            // ignore internal or interop stack frames
            if (rn.isInternal() || rn.getLanguageInfo() == null) {
                return 1;
            }
            if (str.length() > 0) {
                str.append(System.getProperty("line.separator"));
            }
            str.append("Frame: ").append(rn.toString());
            FrameDescriptor frameDescriptor = frame.getFrameDescriptor();
            for (FrameSlot s : frameDescriptor.getSlots()) {
                str.append(", ").append(s.getIdentifier()).append("=").append(frame.getValue(s));
            }
            return null;
        }
    });
    return str.toString();
}
 
示例4
protected void setCallTarget(RootCallTarget callTarget) {
    this.callTarget = callTarget;
    /*
     * We have a new call target. Invalidate all code that speculated that the old call target
     * was stable.
     */
    LOG.log(Level.FINE, "Installed call target for: {0}", name);
    callTargetStable.invalidate();
}
 
示例5
static String getDisplayName(CallTarget ct) {
    if (ct instanceof RootCallTarget) {
        RootNode rn = ((RootCallTarget) ct).getRootNode();
        return getMethodName(rn);
    } else {
        //System.err.println("Unexpected CallTarget: "+ct.getClass());
        return ct.toString();
    }
}
 
示例6
public Map<String, RootCallTarget> getAllFunctions() {
    return allFunctions;
}
 
示例7
@Override
protected CallTarget parse(ParsingRequest request) throws Exception {
    Source source = request.getSource();
    Map<String, RootCallTarget> functions;
    /*
     * Parse the provided source. At this point, we do not have a SLContext yet. Registration of
     * the functions with the SLContext happens lazily in SLEvalRootNode.
     */
    if (request.getArgumentNames().isEmpty()) {
        functions = HashemLanguageParser.parseHashemiLang(this, source);
    } else {
        Source requestedSource = request.getSource();
        StringBuilder sb = new StringBuilder();
        sb.append("bebin azinja(");
        String sep = "";
        for (String argumentName : request.getArgumentNames()) {
            sb.append(sep);
            sb.append(argumentName);
            sep = ",";
        }
        sb.append(") { return ");
        sb.append(request.getSource().getCharacters());
        sb.append(";}");
        String language = requestedSource.getLanguage() == null ? ID : requestedSource.getLanguage();
        Source decoratedSource = Source.newBuilder(language, sb.toString(), request.getSource().getName()).build();
        functions = HashemLanguageParser.parseHashemiLang(this, decoratedSource);
    }

    RootCallTarget main = functions.get("azinja");
    RootNode evalMain;
    if (main != null) {
        /*
         * We have a main function, so "evaluating" the parsed source means invoking that main
         * function. However, we need to lazily register functions into the SLContext first, so
         * we cannot use the original SLRootNode for the main function. Instead, we create a new
         * SLEvalRootNode that does everything we need.
         */
        evalMain = new HashemEvalRootNode(this, main, functions);
    } else {
        /*
         * Even without a main function, "evaluating" the parsed source needs to register the
         * functions into the SLContext.
         */
        evalMain = new HashemEvalRootNode(this, null, functions);
    }
    return Truffle.getRuntime().createCallTarget(evalMain);
}
 
示例8
public HashemEvalRootNode(HashemLanguage language, RootCallTarget rootFunction, Map<String, RootCallTarget> functions) {
    super(language);
    this.functions = functions;
    this.mainCallNode = rootFunction != null ? DirectCallNode.create(rootFunction) : null;
}
 
示例9
/**
 * Associates the {@link HashemBebin} with the given name with the given implementation root
 * node. If the function did not exist before, it defines the function. If the function existed
 * before, it redefines the function and the old implementation is discarded.
 */
public HashemBebin register(String name, RootCallTarget callTarget) {
    HashemBebin function = lookup(name, true);
    function.setCallTarget(callTarget);
    return function;
}
 
示例10
public void register(Map<String, RootCallTarget> newFunctions) {
    for (Map.Entry<String, RootCallTarget> entry : newFunctions.entrySet()) {
        register(entry.getKey(), entry.getValue());
    }
}
 
示例11
public RootCallTarget getCallTarget() {
    return callTarget;
}
 
示例12
public final RootCallTarget getCallTarget() {
    if (callTarget == null) {
        renewCallTarget();
    }
    return callTarget;
}
 
示例13
@TruffleBoundary
@Specialization(guards = {"!receiver.hasMaterializedSender()"})
protected final AbstractSqueakObject findNextAvoidingMaterialization(final ContextObject receiver) {
    final boolean[] foundMyself = new boolean[1];
    final Object[] lastSender = new Object[1];
    final ContextObject result = Truffle.getRuntime().iterateFrames(frameInstance -> {
        final Frame current = frameInstance.getFrame(FrameInstance.FrameAccess.READ_ONLY);
        if (!FrameAccess.isTruffleSqueakFrame(current)) {
            final RootNode rootNode = ((RootCallTarget) frameInstance.getCallTarget()).getRootNode();
            if (rootNode.isInternal() || rootNode.getLanguageInfo().getId().equals(SqueakLanguageConfig.ID)) {
                /* Skip internal and all other nodes that belong to TruffleSqueak. */
                return null;
            } else {
                /*
                 * Found a frame of another language. Stop here by returning the receiver
                 * context. This special case will be handled later on.
                 */
                return receiver;
            }
        }
        final ContextObject context = FrameAccess.getContext(current);
        if (!foundMyself[0]) {
            if (context == receiver) {
                foundMyself[0] = true;
            }
        } else {
            if (FrameAccess.getMethod(current).isExceptionHandlerMarked()) {
                if (context != null) {
                    return context;
                } else {
                    return ContextObject.create(frameInstance);
                }
            } else {
                lastSender[0] = FrameAccess.getSender(current);
            }
        }
        return null;
    });
    if (result == receiver) {
        /*
         * Foreign frame found during frame iteration. Inject a fake context which will
         * throw the Smalltalk exception as polyglot exception.
         */
        return getInteropExceptionThrowingContext();
    } else if (result == null) {
        if (!foundMyself[0]) {
            return findNext(receiver); // Fallback to other version.
        }
        if (lastSender[0] instanceof ContextObject) {
            return findNext((ContextObject) lastSender[0]);
        } else {
            return NilObject.SINGLETON;
        }
    } else {
        return result;
    }
}
 
示例14
public RootCallTarget asCallTarget() {
    return Truffle.getRuntime().createCallTarget(new SqueakImageNode(this));
}
 
示例15
public MumblerFunction(RootCallTarget callTarget) {
    this.callTarget = callTarget;
}
 
示例16
/**
 * Inline cached specialization of the dispatch.
 *
 * <p>
 * SinceHashemiis a quite simple language, the benefit of the inline cache seems small: after
 * checking that the actual function to be executed is the same as the cachedFuntion, we can
 * safely execute the cached call target. You can reasonably argue that caching the call
 * target is overkill, since we could just retrieve it via {@code function.getCallTarget()}.
 * However, caching the call target and using a {@link DirectCallNode} allows Truffle to
 * perform method inlining. In addition, in a more complex language the lookup of the call
 * target is usually much more complicated than in SL.
 * </p>
 *
 * <p>
 * {@code limit = "INLINE_CACHE_SIZE"} Specifies the limit number of inline cache
 * specialization instantiations.
 * </p>
 * <p>
 * {@code guards = "function.getCallTarget() == cachedTarget"} The inline cache check. Note
 * that cachedTarget is a final field so that the compiler can optimize the check.
 * </p>
 * <p>
 * {@code assumptions = "callTargetStable"} Support for function redefinition: When a
 * function is redefined, the call target maintained by the SLFunction object is changed. To
 * avoid a check for that, we use an Assumption that is invalidated by the SLFunction when
 * the change is performed. Since checking an assumption is a no-op in compiled code, the
 * assumption check performed by the DSL does not add any overhead during optimized
 * execution.
 * </p>
 *
 * @see Cached
 * @see Specialization
 *
 * @param function the dynamically provided function
 * @param cachedFunction the cached function of the specialization instance
 * @param callNode the {@link DirectCallNode} specifically created for the
 *            {@link CallTarget} in cachedFunction.
 */
@Specialization(limit = "INLINE_CACHE_SIZE", //
                guards = "function.getCallTarget() == cachedTarget", //
                assumptions = "callTargetStable")
@SuppressWarnings("unused")
protected static Object doDirect(HashemBebin function, Object[] arguments,
                                 @Cached("function.getCallTargetStable()") Assumption callTargetStable,
                                 @Cached("function.getCallTarget()") RootCallTarget cachedTarget,
                                 @Cached("create(cachedTarget)") DirectCallNode callNode) {

    /* Inline cache hit, we are safe to execute the cached call target. */
    Object returnValue = callNode.call(arguments);
    return returnValue;
}
 
示例17
/**
 * Get the nodes hierarchy. Every node is described by:
 * <ul>
 *  <li>node class</li>
 *  <li>node description</li>
 *  <li>node source section - either an empty line, or following items:</li>
 *  <ul>
 *   <li>URI</li>
 *   <li>&lt;start line&gt;:&lt;start column&gt;-&lt;end line&gt;:&lt;end column&gt;</li>
 *  </ul>
 *  <li>number of children</li>
 *  <li>&lt;child nodes follow...&gt;</li>
 * </ul>
 * @return a newline-separated list of elements describing the nodes hierarchy.
 */
public String getNodes() {
    StringBuilder nodes = new StringBuilder();
    RootCallTarget rct = (RootCallTarget) frameInstance.getCallTarget();
    RootNode rootNode = rct.getRootNode();
    fillNode(rootNode, nodes);
    return nodes.toString();
}