Skip to content

Commit

Permalink
Towards using SqueakSSL.so
Browse files Browse the repository at this point in the history
* Add numReceiverAndArguments to InterpreterProxy
* Turn InterpreterProxy into a singleton with mutable members
  frame and numReceiverAndArguments
* objectRegistry is now effectively static, so all primitive
  invocations share an oop namespace
* Implement most InterpreterProxy stubs required for SqueakSSL.so
  • Loading branch information
MariusDoe committed Nov 18, 2023
1 parent bcc3f00 commit 2185699
Show file tree
Hide file tree
Showing 2 changed files with 133 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@
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.model.AbstractSqueakObject;
import de.hpi.swa.trufflesqueak.model.ClassObject;
import de.hpi.swa.trufflesqueak.model.NativeObject;
import de.hpi.swa.trufflesqueak.model.NilObject;
import de.hpi.swa.trufflesqueak.nodes.accessing.SqueakObjectNewNode;
import de.hpi.swa.trufflesqueak.nodes.plugins.ffi.wrappers.NativeObjectStorage;
import de.hpi.swa.trufflesqueak.util.FrameAccess;
import de.hpi.swa.trufflesqueak.util.NFIUtils;
Expand All @@ -19,15 +23,20 @@
import java.util.stream.Collectors;

public class InterpreterProxy {
private static InterpreterProxy INSTANCE = null;

private final VirtualFrame frame;
private final SqueakImageContext context;
private VirtualFrame frame;
private int numReceiverAndArguments;
private final ArrayList<Object> objectRegistry = new ArrayList<>();
private final ArrayList<PostPrimitiveCleanup> postPrimitiveCleanups = new ArrayList<>();

private static Object interpreterProxyPointer = null;

public InterpreterProxy(SqueakImageContext context, VirtualFrame frame) throws UnsupportedMessageException, UnknownIdentifierException, UnsupportedTypeException, ArityException {
private InterpreterProxy(SqueakImageContext context, VirtualFrame frame, int numReceiverAndArguments) throws UnsupportedMessageException, UnknownIdentifierException, UnsupportedTypeException, ArityException {
this.context = context;
this.frame = frame;
this.numReceiverAndArguments = numReceiverAndArguments;
if (interpreterProxyPointer == null) {
final TruffleExecutable[] truffleExecutables = getExecutables();
final String truffleExecutablesSignatures = Arrays.stream(truffleExecutables).map(obj -> obj.nfiSignature).collect(Collectors.joining(","));
Expand All @@ -42,6 +51,20 @@ public InterpreterProxy(SqueakImageContext context, VirtualFrame frame) throws U
interpreterProxy,"createInterpreterProxy", (Object[]) truffleExecutables);
}
}

public static InterpreterProxy instanceFor(SqueakImageContext context, VirtualFrame frame, int numReceiverAndArguments) throws UnsupportedMessageException, UnknownIdentifierException, UnsupportedTypeException, ArityException {
if (INSTANCE == null) {
INSTANCE = new InterpreterProxy(context, frame, numReceiverAndArguments);
return INSTANCE;
}
if (INSTANCE.context != context) {
throw new RuntimeException("InterpreterProxy does not support multiple SqueakImageContexts");
}
INSTANCE.frame = frame;
INSTANCE.numReceiverAndArguments = numReceiverAndArguments;
return INSTANCE;
}

public Object getPointer() {
return interpreterProxyPointer;
}
Expand Down Expand Up @@ -70,69 +93,142 @@ public TruffleExecutable[] getExecutables() {
}
public void postPrimitiveCleanups() {
postPrimitiveCleanups.forEach(PostPrimitiveCleanup::cleanup);
postPrimitiveCleanups.clear();
}
private Object objectRegistryGet(long oop) {
System.out.println("Asked for oop " + oop);
return objectRegistry.get((int) oop);
}

private int addObjectToRegistry(Object object) {
int oop = objectRegistry.size();
objectRegistry.add(object);
return oop;
}

private int oopFor(Object object) {
int oop = objectRegistry.indexOf(object);
if (oop < 0) {
oop = addObjectToRegistry(object);
}
System.out.println("Giving out oop " + oop + " for " + object);
return oop;
}

private int getStackPointer() {
return FrameAccess.getStackPointer(frame);
}

private void setStackPointer(int stackPointer) {
FrameAccess.setStackPointer(frame, stackPointer);
}

private void pushObject(Object object) {
System.out.println("Pushing object " + object);
int stackPointer = getStackPointer() + 1;
setStackPointer(stackPointer);
FrameAccess.setSlot(frame, stackPointer, object);
}
private NativeObject objectRegistryGet(long oop) {
return (NativeObject) objectRegistry.get((int) oop);

private Object getObjectOnStack(long reverseStackIndex) {
if (reverseStackIndex < 0) {
primitiveFail();
return null;
}
int stackIndex = getStackPointer() - (int) reverseStackIndex;
if (stackIndex < 0) {
primitiveFail();
return null;
}
return FrameAccess.getStackValue(frame, stackIndex, FrameAccess.getNumArguments(frame));
}

private long objectToLong(Object object) {
if (!(object instanceof Long)) {
System.out.println("Object to long called with non-Long: " + object);
primitiveFail();
return 0;
}
return (Long)object;
}

private int byteSizeOf(long oop) {
return NativeObjectStorage.from(objectRegistryGet(oop)).byteSizeOf();
return NativeObjectStorage.from((NativeObject) objectRegistryGet(oop)).byteSizeOf();
}
private int classString() {
return 1;// TODO
return oopFor(context.byteStringClass);
}
private int failed() {
return 1;// TODO
return 0; // TODO: when changing primitiveFail to continue executing, properly implement this
}
private NativeObjectStorage firstIndexableField(long oop) {
NativeObjectStorage storage = NativeObjectStorage.from(objectRegistryGet(oop));
NativeObjectStorage storage = NativeObjectStorage.from((NativeObject) objectRegistryGet(oop));
postPrimitiveCleanups.add(storage);
return storage;
}
private int instantiateClassindexableSize(long classPointer, long size) {
return 1;// TODO
Object classObject = objectRegistryGet(classPointer);
if (!(classObject instanceof ClassObject)) {
System.out.println("instantiateClassindexableSize called with non-ClassObject: " + classObject);
primitiveFail();
return -1;
}
SqueakObjectNewNode objectNewNode = SqueakObjectNewNode.create();
AbstractSqueakObject newObject = objectNewNode.execute(context, (ClassObject) classObject, (int)size);
return oopFor(newObject);
}
private int isBytes(long oop) {
return objectRegistryGet(oop).isByteType() ? 1 : 0;
Object object = objectRegistryGet(oop);
if (!(object instanceof NativeObject)) {
return 0;
}
return ((NativeObject) object).isByteType() ? 1 : 0;
}
private int majorVersion() {
return 1;
}
private int methodArgumentCount() {
return FrameAccess.getNumArguments(frame);
return numReceiverAndArguments - 1;
}
private int minorVersion() {
return 17;
}
private int nilObject() {
return 1;// TODO
return oopFor(NilObject.SINGLETON);
}
private int pop(long nItems) {
return 1;// TODO
setStackPointer(getStackPointer() - (int)nItems);
return 1;
}
private int popthenPush(long nItems, long oop) {
return 1;// TODO
pop(nItems);
push(oop);
return 1;
}
private int primitiveFail() {
// TODO: continue executing C code
// TODO: adjust failed accordingly
throw PrimitiveFailed.GENERIC_ERROR;
}
private int pushInteger(long integerValue) {
return 1;// TODO
pushObject(integerValue);
return 1;
}
private int push(long oop) {
pushObject(objectRegistryGet(oop));
return 1;
}
private int signed32BitIntegerFor(long integerValue) {
return 1;// TODO
return oopFor(integerValue);
}
private int signed32BitValueOf(long oop) {
return 1;// TODO
return (int)objectToLong(objectRegistryGet(oop));
}
private int stackIntegerValue(long stackIndex) {
return 1;// TODO
private long stackIntegerValue(long reverseStackIndex) {
return objectToLong(getObjectOnStack(reverseStackIndex));
}
private int stackValue(long stackIndex) {
Object objectOnStack = FrameAccess.getStackValue(frame, (int) stackIndex, FrameAccess.getNumArguments(frame));
int objectIndex = objectRegistry.size();
objectRegistry.add(objectOnStack);
return objectIndex;
private int stackValue(long reverseStackIndex) {
return oopFor(getObjectOnStack(reverseStackIndex));
}

public interface PostPrimitiveCleanup {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@
import de.hpi.swa.trufflesqueak.nodes.plugins.SecurityPlugin;
import de.hpi.swa.trufflesqueak.nodes.plugins.SoundCodecPrims;
import de.hpi.swa.trufflesqueak.nodes.plugins.SqueakFFIPrims;
import de.hpi.swa.trufflesqueak.nodes.plugins.SqueakSSL;
import de.hpi.swa.trufflesqueak.nodes.plugins.TruffleSqueakPlugin;
import de.hpi.swa.trufflesqueak.nodes.plugins.UUIDPlugin;
import de.hpi.swa.trufflesqueak.nodes.plugins.UnixOSProcessPlugin;
import de.hpi.swa.trufflesqueak.nodes.plugins.Win32OSProcessPlugin;
import de.hpi.swa.trufflesqueak.nodes.plugins.ZipPlugin;
Expand Down Expand Up @@ -114,8 +114,8 @@ public final class PrimitiveNodeFactory {
new SocketPlugin(),
new SoundCodecPrims(),
new SqueakFFIPrims(),
new SqueakSSL(),
//new UUIDPlugin(),
//new SqueakSSL(),
new UUIDPlugin(),
new ZipPlugin(),
OS.isWindows() ? new Win32OSProcessPlugin() : new UnixOSProcessPlugin()};
fillPrimitiveTable(plugins);
Expand Down Expand Up @@ -210,36 +210,38 @@ public static AbstractPrimitiveNode getOrCreateNamed(final CompiledCodeObject me
if (functionName.equals("primitivePluginVersion")) {
return null;
}
return new NonExistentPrimitiveNode(moduleName, functionName);
return new NonExistentPrimitiveNode(moduleName, functionName, numReceiverAndArguments);
}
}

static class NonExistentPrimitiveNode extends AbstractPrimitiveNode {
final String moduleName;
final String functionName;
final int numReceiverAndArguments;

public NonExistentPrimitiveNode(String moduleName, String functionName) {
public NonExistentPrimitiveNode(String moduleName, String functionName, int numReceiverAndArguments) {
this.moduleName = moduleName;
this.functionName = functionName;
this.numReceiverAndArguments = numReceiverAndArguments;
}

@Override
public Object execute(VirtualFrame frame) {
final Object uuidPlugin = NFIUtils.loadLibrary(getContext(), "UUIDPlugin.so", "{ " +
"initialiseModule():SINT64; " +
final Object uuidPlugin = NFIUtils.loadLibrary(getContext(), "SqueakSSL.so", "{ " +
//"initialiseModule():SINT64; " +
"setInterpreter(POINTER):SINT64; " +
"shutdownModule():SINT64; " +
//"shutdownModule():SINT64; " +
functionName + "():SINT64; " +
" }");
final InteropLibrary uuidPluginLibrary = NFIUtils.getInteropLibrary(uuidPlugin);
InterpreterProxy interpreterProxy = null;
try {
interpreterProxy = new InterpreterProxy(getContext(), frame);
interpreterProxy = InterpreterProxy.instanceFor(getContext(), frame, numReceiverAndArguments);

uuidPluginLibrary.invokeMember(uuidPlugin, "initialiseModule");
//uuidPluginLibrary.invokeMember(uuidPlugin, "initialiseModule");
uuidPluginLibrary.invokeMember(uuidPlugin, "setInterpreter", interpreterProxy.getPointer());
final Object result = uuidPluginLibrary.invokeMember(uuidPlugin, functionName);
uuidPluginLibrary.invokeMember(uuidPlugin, "shutdownModule");
//uuidPluginLibrary.invokeMember(uuidPlugin, "shutdownModule");

return result;
} catch (Exception e) {
Expand Down

0 comments on commit 2185699

Please sign in to comment.