Set<Class<?>> getProvidedTags(LanguageInfo language) { Nodes nodesAccess = AccessorInstrumentHandler.nodesAccess(); TruffleLanguage<?> lang = nodesAccess.getLanguageSpi(language); if (lang == null) { return Collections.emptySet(); } Class<?> languageClass = lang.getClass(); Set<Class<?>> tags = cachedProvidedTags.get(languageClass); if (tags == null) { ProvidedTags languageTags = languageClass.getAnnotation(ProvidedTags.class); List<Class<?>> languageTagsList = languageTags != null ? Arrays.asList(languageTags.value()) : Collections.<Class<?>> emptyList(); tags = Collections.unmodifiableSet(new HashSet<>(languageTagsList)); cachedProvidedTags.put(languageClass, tags); } return tags; }
@Override void verifyFilter(SourceSectionFilter filter) { Set<Class<?>> providedTags = getProvidedTags(languageInfo); // filters must not reference tags not declared in @RequiredTags Set<Class<?>> referencedTags = filter.getReferencedTags(); if (!providedTags.containsAll(referencedTags)) { Set<Class<?>> missingTags = new HashSet<>(referencedTags); missingTags.removeAll(providedTags); Set<Class<?>> allTags = new LinkedHashSet<>(providedTags); allTags.addAll(missingTags); StringBuilder builder = new StringBuilder("{"); String sep = ""; for (Class<?> tag : allTags) { builder.append(sep); builder.append(tag.getSimpleName()); sep = ", "; } builder.append("}"); Nodes langAccess = AccessorInstrumentHandler.nodesAccess(); TruffleLanguage<?> lang = langAccess.getLanguageSpi(languageInfo); throw new IllegalArgumentException(String.format("The attached filter %s references the following tags %s which are not declared as provided by the language. " + "To fix this annotate the language class %s with @%s(%s).", filter, missingTags, lang.getClass().getName(), ProvidedTags.class.getSimpleName(), builder)); } }
@SuppressWarnings("rawtypes") PolyglotLanguageContext findLanguageContext(Class<? extends TruffleLanguage> languageClazz, boolean failIfNotFound) { for (PolyglotLanguageContext lang : contexts) { Env env = lang.env; if (env != null) { TruffleLanguage<?> language = NODES.getLanguageSpi(lang.language.info); if (languageClazz != TruffleLanguage.class && languageClazz.isInstance(language)) { return lang; } } } if (failIfNotFound) { Set<String> languageNames = new HashSet<>(); for (PolyglotLanguageContext lang : contexts) { if (lang.env == null) { continue; } languageNames.add(lang.language.cache.getClassName()); } throw new IllegalStateException("Cannot find language " + languageClazz + " among " + languageNames); } else { return null; } }
ExecutableNode fragment = null; CallTarget target = null; fragment = API.nodes().getLanguageSpi(info).parseInline(source, node, mFrame); if (fragment == null) { target = API.nodes().getLanguageSpi(info).parse(source, node, mFrame);
/** * Returns an additional service provided by the given language, specified by type. If an * language is not loaded, it will not be automatically loaded by requesting a service. In * order to ensure a language to be loaded at least one {@link Source} must be * {@link #parse(Source, String...) parsed} first. * * @param <S> the requested type * @param language the language to query * @param type the class of the requested type * @return the registered service or <code>null</code> if none is found * @since 0.26 */ @TruffleBoundary public <S> S lookup(@SuppressWarnings("hiding") LanguageInfo language, Class<S> type) { if (this.language == language) { throw new IllegalArgumentException("Cannot request services from the current language."); } TruffleLanguage<?> otherSpi = AccessAPI.nodesAccess().getLanguageSpi(language); return otherSpi.lookup(type); }
Language findLanguage(Class<? extends TruffleLanguage> languageClazz, boolean onlyInitialized, boolean failIfNotFound) { for (Language lang : languageArray) { assert lang.shared.language != null; if (onlyInitialized && lang.getEnv(false) == null) { continue; } TruffleLanguage<?> spi = NODES.getLanguageSpi(lang.shared.language); if (languageClazz.isInstance(spi)) { return lang; } } if (failIfNotFound) { Set<String> languageNames = new HashSet<>(); for (Language lang : languageArray) { languageNames.add(lang.shared.cache.getClassName()); } throw new IllegalStateException("Cannot find language " + languageClazz + " among " + languageNames); } else { return null; } }
@SuppressWarnings("unchecked") private Env(Object vmObject, LanguageInfo language, OutputStream out, OutputStream err, InputStream in, Map<String, Object> config, OptionValues options, String[] applicationArguments) { this.vmObject = vmObject; this.language = language; this.spi = (TruffleLanguage<Object>) API.nodes().getLanguageSpi(language); this.in = in; this.err = err; this.out = out; this.config = config; this.options = options; this.applicationArguments = applicationArguments == null ? new String[0] : applicationArguments; this.valid = true; }
@SuppressWarnings("unchecked") @Override public <T extends TruffleLanguage<?>> T getCurrentLanguage(Class<T> languageClass) { CompilerAsserts.partialEvaluationConstant(languageClass); PolyglotContextImpl context = PolyglotContextImpl.requireContext(); return (T) NODES.getLanguageSpi(context.getLanguageContext(languageClass).language.info); }
@SuppressWarnings("unchecked") @Override public TruffleLanguage<C> getTruffleLanguage() { return (TruffleLanguage<C>) NODES.getLanguageSpi(polyglotLanguage.info); } }
@Override public <S> S lookup(LanguageInfo language, Class<S> type) { return TruffleLanguage.AccessAPI.nodesAccess().getLanguageSpi(language).lookup(type); }
@Override public <T extends TruffleLanguage<?>> T getCurrentLanguage(Class<T> languageClass) { PolyglotEngine engine = PolyglotEngine.GLOBAL_PROFILE.get(); if (engine == null) { CompilerDirectives.transferToInterpreter(); throw new IllegalStateException("No current language available."); } Language language = engine.getLanguage(languageClass); return languageClass.cast(NODES.getLanguageSpi(language.shared.language)); }
@SuppressWarnings("unchecked") @Override public TruffleLanguage<C> getTruffleLanguage() { return (TruffleLanguage<C>) NODES.getLanguageSpi(LANGUAGE.getLanguageInfo(env)); } }
@Override public boolean isThreadAccessAllowed(LanguageInfo language, Thread thread, boolean singleThread) { return AccessAPI.nodesAccess().getLanguageSpi(language).isThreadAccessAllowed(thread, singleThread); }
static <T extends TruffleLanguage<?>> T findLanguageByClass(Object vm, Class<T> languageClass) { Env env = SPI.findEnv(vm, languageClass, true); TruffleLanguage<?> language = NODES.getLanguageSpi(API.getLanguageInfo(env)); return languageClass.cast(language); }