com.oracle.truffle.api.instrumentation.InstrumentAccessor Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of truffle-api Show documentation
Show all versions of truffle-api Show documentation
Truffle is a multi-language framework for executing dynamic languages
that achieves high performance when combined with Graal.
/*
* Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
*
* Subject to the condition set forth below, permission is hereby granted to any
* person obtaining a copy of this software, associated documentation and/or
* data (collectively the "Software"), free of charge and under any and all
* copyright rights in the Software, and any and all patent rights owned or
* freely licensable by each licensor hereunder covering either (i) the
* unmodified Software as contributed to or provided by such licensor, or (ii)
* the Larger Works (as defined below), to deal in both
*
* (a) the Software, and
*
* (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
* one is included with the Software each a "Larger Work" to which the Software
* is contributed by such licensors),
*
* without restriction, including without limitation the rights to copy, create
* derivative works of, display, perform, and distribute the Software and make,
* use, sell, offer for sale, import, export, have made, and have sold the
* Software and the Larger Work(s), and to sublicense the foregoing rights on
* either these or other terms.
*
* This license is subject to the following condition:
*
* The above copyright notice and either this complete permission notice or at a
* minimum a reference to the UPL must be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.oracle.truffle.api.instrumentation;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.function.Supplier;
import org.graalvm.options.OptionDescriptor;
import org.graalvm.options.OptionDescriptors;
import org.graalvm.options.OptionValues;
import org.graalvm.polyglot.io.MessageTransport;
import com.oracle.truffle.api.CallTarget;
import com.oracle.truffle.api.CompilerAsserts;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.TruffleContext;
import com.oracle.truffle.api.TruffleLanguage;
import com.oracle.truffle.api.impl.Accessor;
import com.oracle.truffle.api.impl.DispatchOutputStream;
import com.oracle.truffle.api.instrumentation.InstrumentationHandler.InstrumentClientInstrumenter;
import com.oracle.truffle.api.instrumentation.TruffleInstrument.ContextLocalFactory;
import com.oracle.truffle.api.instrumentation.TruffleInstrument.ContextThreadLocalFactory;
import com.oracle.truffle.api.nodes.ExplodeLoop;
import com.oracle.truffle.api.nodes.LanguageInfo;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.nodes.RootNode;
final class InstrumentAccessor extends Accessor {
static final InstrumentAccessor ACCESSOR = new InstrumentAccessor();
static final NodeSupport NODES = ACCESSOR.nodeSupport();
static final SourceSupport SOURCE = ACCESSOR.sourceSupport();
static final JDKSupport JDK = ACCESSOR.jdkSupport();
static final LanguageSupport LANGUAGE = ACCESSOR.languageSupport();
static final EngineSupport ENGINE = ACCESSOR.engineSupport();
static final InteropSupport INTEROP = ACCESSOR.interopSupport();
private InstrumentAccessor() {
}
static NodeSupport nodesAccess() {
return ACCESSOR.nodeSupport();
}
static LanguageSupport langAccess() {
return ACCESSOR.languageSupport();
}
static EngineSupport engineAccess() {
return ACCESSOR.engineSupport();
}
static InteropSupport interopAccess() {
return ACCESSOR.interopSupport();
}
static RuntimeSupport runtimeAccess() {
return ACCESSOR.runtimeSupport();
}
protected boolean isTruffleObject(Object value) {
return interopSupport().isTruffleObject(value);
}
static final class InstrumentImpl extends InstrumentSupport {
@Override
public Object createInstrumentationHandler(Object polyglotEngine, DispatchOutputStream out, DispatchOutputStream err, InputStream in, MessageTransport messageInterceptor,
boolean strongReferences) {
return new InstrumentationHandler(polyglotEngine, out, err, in, messageInterceptor);
}
@Override
public void initializeInstrument(Object instrumentationHandler, Object polyglotInstrument, String instrumentClassName, Supplier extends Object> instrumentSupplier) {
((InstrumentationHandler) instrumentationHandler).initializeInstrument(polyglotInstrument, instrumentClassName, instrumentSupplier);
}
@Override
public void createInstrument(Object instrumentationHandler, Object polyglotInstrument, String[] expectedServices, OptionValues options) {
((InstrumentationHandler) instrumentationHandler).createInstrument(polyglotInstrument, expectedServices, options);
}
@Override
public Object getEngineInstrumenter(Object instrumentationHandler) {
return ((InstrumentationHandler) instrumentationHandler).engineInstrumenter;
}
@Override
public void onNodeInserted(RootNode rootNode, Node tree) {
InstrumentationHandler handler = getHandler(rootNode);
if (handler != null) {
handler.onNodeInserted(rootNode, tree);
}
}
@Override
public OptionDescriptors describeEngineOptions(Object instrumentationHandler, Object key, String requiredGroup) {
InstrumentClientInstrumenter instrumenter = (InstrumentClientInstrumenter) ((InstrumentationHandler) instrumentationHandler).instrumenterMap.get(key);
OptionDescriptors descriptors = instrumenter.instrument.getOptionDescriptors();
return validateOptions(requiredGroup, instrumenter, descriptors);
}
@Override
public OptionDescriptors describeContextOptions(Object instrumentationHandler, Object key, String requiredGroup) {
InstrumentClientInstrumenter instrumenter = (InstrumentClientInstrumenter) ((InstrumentationHandler) instrumentationHandler).instrumenterMap.get(key);
OptionDescriptors descriptors = instrumenter.instrument.getContextOptionDescriptors();
return validateOptions(requiredGroup, instrumenter, descriptors);
}
private static OptionDescriptors validateOptions(String requiredGroup, InstrumentClientInstrumenter instrumenter, OptionDescriptors descriptors) {
if (descriptors == null) {
return OptionDescriptors.EMPTY;
}
String groupPlusDot = requiredGroup + ".";
for (OptionDescriptor descriptor : descriptors) {
if (!descriptor.getName().equals(requiredGroup) && !descriptor.getName().startsWith(groupPlusDot)) {
throw new IllegalArgumentException(String.format("Illegal option prefix in name '%s' specified for option described by instrument '%s'. " +
"The option prefix must match the id of the instrument '%s'.",
descriptor.getName(), instrumenter.instrument.getClass().getName(), requiredGroup));
}
}
return descriptors;
}
@Override
public void finalizeInstrument(Object instrumentationHandler, Object polyglotInstrument) {
((InstrumentationHandler) instrumentationHandler).finalizeInstrumenter(polyglotInstrument);
}
@Override
public void disposeInstrument(Object instrumentationHandler, Object polyglotInstrument, boolean cleanupRequired) {
((InstrumentationHandler) instrumentationHandler).disposeInstrumenter(polyglotInstrument, cleanupRequired);
}
@Override
public void collectEnvServices(Set