Skip to content

Commit

Permalink
Extract loading from execute
Browse files Browse the repository at this point in the history
  • Loading branch information
DieKautz committed Jan 11, 2024
1 parent 6ae678b commit 95fc76e
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 30 deletions.
Original file line number Diff line number Diff line change
@@ -1,51 +1,73 @@
package de.hpi.swa.trufflesqueak.nodes.plugins.ffi;

import java.util.HashMap;
import java.util.Map;

import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.frame.MaterializedFrame;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.interop.ArityException;
import com.oracle.truffle.api.interop.InteropLibrary;

import com.oracle.truffle.api.interop.UnknownIdentifierException;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.interop.UnsupportedTypeException;
import de.hpi.swa.trufflesqueak.exceptions.PrimitiveFailed;
import de.hpi.swa.trufflesqueak.image.SqueakImageContext;
import de.hpi.swa.trufflesqueak.nodes.primitives.AbstractPrimitiveNode;
import de.hpi.swa.trufflesqueak.util.FrameAccess;
import de.hpi.swa.trufflesqueak.util.NFIUtils;

import java.util.HashMap;
import java.util.Map;

public final class PrimExternalCallNode extends AbstractPrimitiveNode {
private final String moduleName;
private final String functionName;
private final Object moduleLibrary;
private final InteropLibrary moduleInteropLibrary;
private final Object functionSymbol;
private final InteropLibrary functionInteropLibrary;
private final int numReceiverAndArguments;
private static final Map<String, Object> loadedLibraries = new HashMap<>();

public PrimExternalCallNode(final String moduleName, final String functionName, final int numReceiverAndArguments) {
this.moduleName = moduleName;
this.functionName = functionName;
public PrimExternalCallNode(final Object moduleLibrary, final InteropLibrary moduleInteropLibrary, final Object functionSymbol, final InteropLibrary functionInteropLibrary,
final int numReceiverAndArguments) {
this.moduleLibrary = moduleLibrary;
this.moduleInteropLibrary = moduleInteropLibrary;
this.functionSymbol = functionSymbol;
this.functionInteropLibrary = functionInteropLibrary;
this.numReceiverAndArguments = numReceiverAndArguments;
}

public static PrimExternalCallNode load(final String moduleName, final String functionName, final int numReceiverAndArguments)
throws UnsupportedMessageException, UnknownIdentifierException, UnsupportedTypeException, ArityException {
final SqueakImageContext context = SqueakImageContext.getSlow();
final Object moduleLibrary = loadedLibraries.computeIfAbsent(moduleName, (String s) -> NFIUtils.loadLibrary(context, moduleName, "{ " +
// TODO, see below
// "initialiseModule():SINT64; " +
"setInterpreter(POINTER):SINT64; " +
// Currently not called, since plugins are never unloaded
// "shutdownModule():SINT64; " +
" }"));
if (moduleLibrary == null) {
return null;
}
final InteropLibrary moduleInteropLibrary = NFIUtils.getInteropLibrary(moduleLibrary);

final Object functionSymbol = NFIUtils.loadMember(context, moduleLibrary, functionName, "():SINT64");
final InteropLibrary functionInteropLibrary = NFIUtils.getInteropLibrary(functionSymbol);

return new PrimExternalCallNode(moduleLibrary, moduleInteropLibrary, functionSymbol, functionInteropLibrary, numReceiverAndArguments);
}

@Override
public Object execute(final VirtualFrame frame) {
return doExternalCall(frame.materialize());
}

@Override
public Object executeWithArguments(final VirtualFrame frame, final Object... receiverAndArguments) {
// arguments are handled via manipulation of the stack pointer, see above
// arguments are handled via manipulation of the stack pointer, see below
return execute(frame);
}

@TruffleBoundary
private Object doExternalCall(final MaterializedFrame frame) {
final Object moduleLibrary = loadedLibraries.computeIfAbsent(moduleName, (String s) -> NFIUtils.loadLibrary(getContext(), moduleName, "{ " +
// TODO, see below
// "initialiseModule():SINT64; " +
"setInterpreter(POINTER):SINT64; " +
// Currently not called, since plugins are never unloaded
// "shutdownModule():SINT64; " +
" }"));
final InteropLibrary moduleInteropLibrary = NFIUtils.getInteropLibrary(moduleLibrary);
InterpreterProxy interpreterProxy = null;
try {
interpreterProxy = InterpreterProxy.instanceFor(getContext(), frame, numReceiverAndArguments);
Expand All @@ -61,16 +83,12 @@ private Object doExternalCall(final MaterializedFrame frame) {

moduleInteropLibrary.invokeMember(moduleLibrary, "setInterpreter", InterpreterProxy.getPointer());

final Object functionSymbol = NFIUtils.loadMember(getContext(), moduleLibrary, functionName, "():SINT64");
final InteropLibrary functionInteropLibrary = NFIUtils.getInteropLibrary(functionSymbol);
// return value is unused, the actual return value is pushed onto the stack (see below)
functionInteropLibrary.execute(functionSymbol);

// The return value is pushed onto the stack by the plugin via the InterpreterProxy, but
// TruffleSqueak
// expects the return value to be returned by this function
// (AbstractSendNode.executeVoid).
// Pop the return value and return it.
// TruffleSqueak expects the return value to be returned by this function
// (AbstractSendNode.executeVoid). Pop the return value and return it.
final Object returnValue = FrameAccess.getStackValue(frame, FrameAccess.getStackPointer(frame) - 1, FrameAccess.getNumArguments(frame));
FrameAccess.setStackPointer(frame, FrameAccess.getStackPointer(frame) - 1);
return returnValue;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
package de.hpi.swa.trufflesqueak.nodes.primitives;

import com.oracle.truffle.api.dsl.NodeFactory;
import com.oracle.truffle.api.interop.ArityException;
import com.oracle.truffle.api.interop.UnknownIdentifierException;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.interop.UnsupportedTypeException;
import de.hpi.swa.trufflesqueak.model.ArrayObject;
import de.hpi.swa.trufflesqueak.model.CompiledCodeObject;
import de.hpi.swa.trufflesqueak.model.NativeObject;
Expand Down Expand Up @@ -206,7 +210,12 @@ public static AbstractPrimitiveNode getOrCreateNamed(final CompiledCodeObject me
if (moduleName.equals("SqueakFFIPrims")) {
return null;
}
return new PrimExternalCallNode(moduleName, functionName, numReceiverAndArguments);
try {
return PrimExternalCallNode.load(moduleName, functionName, numReceiverAndArguments);
} catch (UnsupportedMessageException | UnknownIdentifierException | ArityException | UnsupportedTypeException e) {
assert false : e.getMessage();
return null;
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package de.hpi.swa.trufflesqueak.util;

import java.io.File;

import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.TruffleFile;
import com.oracle.truffle.api.interop.ArityException;
Expand All @@ -13,10 +11,10 @@
import com.oracle.truffle.api.library.ExportLibrary;
import com.oracle.truffle.api.library.ExportMessage;
import com.oracle.truffle.api.source.Source;

import de.hpi.swa.trufflesqueak.exceptions.PrimitiveFailed;
import de.hpi.swa.trufflesqueak.image.SqueakImageContext;

import java.io.File;

public final class NFIUtils {

@ExportLibrary(InteropLibrary.class)
Expand Down Expand Up @@ -155,7 +153,7 @@ public static Object loadLibrary(final SqueakImageContext context, final String
final String libName = System.mapLibraryName(moduleName);
final TruffleFile libPath = context.getHomePath().resolve("lib" + File.separatorChar + libName);
if (!libPath.exists()) {
throw PrimitiveFailed.GENERIC_ERROR;
return null;
}
final String nfiCode = "load \"" + libPath.getAbsoluteFile().getPath() + "\" " + boundSymbols;
return executeNFI(context, nfiCode);
Expand Down

0 comments on commit 95fc76e

Please sign in to comment.