com.oracle.svm.truffle.nfi.TruffleNFISupport Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of truffle-runtime-svm Show documentation
Show all versions of truffle-runtime-svm Show documentation
SVM Runtime for Truffle languages.
/*
* Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.oracle.svm.truffle.nfi;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import org.graalvm.nativeimage.ImageSingletons;
import org.graalvm.nativeimage.ObjectHandle;
import org.graalvm.nativeimage.ObjectHandles;
import org.graalvm.nativeimage.c.type.CCharPointer;
import org.graalvm.nativeimage.c.type.CTypeConversion;
import org.graalvm.word.SignedWord;
import org.graalvm.word.UnsignedWord;
import org.graalvm.word.WordFactory;
import com.oracle.svm.core.SubstrateUtil;
import com.oracle.svm.core.threadlocal.FastThreadLocalFactory;
import com.oracle.svm.core.threadlocal.FastThreadLocalObject;
import com.oracle.svm.truffle.nfi.NativeAPI.TruffleContextHandle;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
public abstract class TruffleNFISupport {
static final Charset UTF8 = Charset.forName("utf8");
private static final FastThreadLocalObject currentScope = FastThreadLocalFactory.createObject(LocalNativeScope.class, "TruffleNFISupport.currentScope");
private final ObjectHandles globalHandles;
private final ObjectHandles closureHandles;
private final ObjectHandles contextHandles;
public final String errnoGetterFunctionName;
protected TruffleNFISupport(String errnoLocation) {
errnoGetterFunctionName = errnoLocation;
globalHandles = ObjectHandles.create();
closureHandles = ObjectHandles.create();
contextHandles = ObjectHandles.create();
}
public static LocalNativeScope createLocalScope(int pinCount) {
LocalNativeScope parent = currentScope.get();
LocalNativeScope ret = new LocalNativeScope(parent, pinCount);
currentScope.set(ret);
return ret;
}
public static void closeLocalScope(LocalNativeScope current, LocalNativeScope parent) {
assert currentScope.get() == current;
currentScope.set(parent);
}
public static TruffleObjectHandle createLocalHandle(Object obj) {
return currentScope.get().createLocalHandle(obj);
}
public TruffleObjectHandle createGlobalHandle(Object obj) {
return (TruffleObjectHandle) globalHandles.create(obj);
}
public void destroyGlobalHandle(TruffleObjectHandle handle) {
SignedWord word = (SignedWord) handle;
if (word.greaterThan(0)) {
globalHandles.destroy((ObjectHandle) word);
}
}
public Object resolveHandle(TruffleObjectHandle handle) {
SignedWord word = (SignedWord) handle;
if (word.equal(0)) {
return null;
} else if (word.greaterThan(0)) {
return globalHandles.get((ObjectHandle) word);
} else {
return currentScope.get().resolveLocalHandle(handle);
}
}
public LibFFI.NativeClosureHandle createClosureHandle(NativeClosure closure) {
return (LibFFI.NativeClosureHandle) closureHandles.create(closure);
}
public NativeClosure resolveClosureHandle(LibFFI.NativeClosureHandle handle) {
return (NativeClosure) closureHandles.get((ObjectHandle) handle);
}
public void destroyClosureHandle(LibFFI.NativeClosureHandle handle) {
closureHandles.destroy((ObjectHandle) handle);
}
public TruffleContextHandle createContextHandle(Target_com_oracle_truffle_nfi_backend_libffi_LibFFIContext context) {
return (TruffleContextHandle) contextHandles.create(context);
}
public Target_com_oracle_truffle_nfi_backend_libffi_LibFFIContext resolveContextHandle(TruffleContextHandle handle) {
return (Target_com_oracle_truffle_nfi_backend_libffi_LibFFIContext) contextHandles.get((ObjectHandle) handle);
}
public void destroyContextHandle(TruffleContextHandle handle) {
contextHandles.destroy((ObjectHandle) handle);
}
@TruffleBoundary
public static String utf8ToJavaString(CCharPointer str) {
if (str.equal(WordFactory.zero())) {
return null;
} else {
UnsignedWord len = SubstrateUtil.strlen(str);
ByteBuffer buffer = CTypeConversion.asByteBuffer(str, (int) len.rawValue());
return UTF8.decode(buffer).toString();
}
}
private static final class ZeroTerminatedCharSequence implements CharSequence {
private CharSequence seq;
ZeroTerminatedCharSequence(CharSequence seq) {
this.seq = seq;
}
@Override
public int length() {
return seq.length() + 1;
}
@Override
public char charAt(int index) {
if (index == seq.length()) {
return '\0';
} else {
return seq.charAt(index);
}
}
@Override
public CharSequence subSequence(int start, int end) {
if (end == length()) {
return new ZeroTerminatedCharSequence(seq.subSequence(start, end - 1));
} else {
return seq.subSequence(start, end);
}
}
}
@TruffleBoundary
public static byte[] javaStringToUtf8(String str) {
CharBuffer input = CharBuffer.wrap(new ZeroTerminatedCharSequence(str));
/*
* No need to trim the result array. The string is zero terminated, and the array is only
* accessed from native code, which ignores the array length anyway.
*/
return UTF8.encode(input).array();
}
protected abstract CCharPointer strdupImpl(CCharPointer src);
protected abstract long loadLibraryImpl(long nativeContext, String name, int flags);
protected abstract void freeLibraryImpl(long library);
protected abstract long lookupImpl(long nativeContext, long library, String name);
public static CCharPointer strdup(CCharPointer src) {
TruffleNFISupport truffleNFISupport = ImageSingletons.lookup(TruffleNFISupport.class);
return truffleNFISupport.strdupImpl(src);
}
public static long loadLibrary(long nativeContext, String name, int flags) {
TruffleNFISupport truffleNFISupport = ImageSingletons.lookup(TruffleNFISupport.class);
return truffleNFISupport.loadLibraryImpl(nativeContext, name, flags);
}
public static void freeLibrary(long library) {
TruffleNFISupport truffleNFISupport = ImageSingletons.lookup(TruffleNFISupport.class);
truffleNFISupport.freeLibraryImpl(library);
}
public static long lookup(long nativeContext, long library, String name) {
TruffleNFISupport truffleNFISupport = ImageSingletons.lookup(TruffleNFISupport.class);
return truffleNFISupport.lookupImpl(nativeContext, library, name);
}
protected static Target_com_oracle_truffle_nfi_backend_libffi_LibFFIContext getContext(long nativeContext) {
TruffleNFISupport truffleNFISupport = ImageSingletons.lookup(TruffleNFISupport.class);
NativeAPI.NativeTruffleContext ctx = WordFactory.pointer(nativeContext);
return truffleNFISupport.resolveContextHandle(ctx.contextHandle());
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy