Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Make native call sites nested in P6opaque work.
With this, we can have NativeCall basically working on JVM (will need
work on CArray and CStruct before we have full support, though).
  • Loading branch information
jnthn committed Oct 12, 2013
1 parent 0040bf6 commit 764b127
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 6 deletions.
16 changes: 11 additions & 5 deletions src/vm/jvm/runtime/org/perl6/nqp/runtime/NativeCallOps.java
Expand Up @@ -3,6 +3,8 @@
import com.sun.jna.NativeLibrary;
import com.sun.jna.Pointer;

import org.perl6.nqp.sixmodel.REPR;
import org.perl6.nqp.sixmodel.REPRRegistry;
import org.perl6.nqp.sixmodel.SixModelObject;

import org.perl6.nqp.sixmodel.reprs.CPointerInstance;
Expand All @@ -18,7 +20,7 @@ public static long init() {
}

public static long build(SixModelObject target, String libname, String symbol, String convention, SixModelObject arguments, SixModelObject returns, ThreadContext tc) {
NativeCallBody call = getNativeCallBody(target);
NativeCallBody call = getNativeCallBody(tc, target);

try {
/* Load the library and locate the symbol. */
Expand Down Expand Up @@ -47,7 +49,7 @@ public static long build(SixModelObject target, String libname, String symbol, S
}

public static SixModelObject call(SixModelObject returns, SixModelObject callObject, SixModelObject arguments, ThreadContext tc) {
NativeCallBody call = getNativeCallBody(callObject);
NativeCallBody call = getNativeCallBody(tc, callObject);

try {
/* Convert arguments into array of appropriate objects. */
Expand All @@ -74,14 +76,18 @@ public static long refresh(SixModelObject obj) {
return 1L;
}

private static NativeCallBody getNativeCallBody(SixModelObject target) {
private static REPR ncrepr = REPRRegistry.getByName("NativeCall");
private static NativeCallBody getNativeCallBody(ThreadContext tc, SixModelObject target) {
NativeCallBody call;
if (target instanceof NativeCallInstance) {
call = ((NativeCallInstance)target).body;
}
else {
/* TODO: Handle box target stuff here. */
call = null;
call = (NativeCallBody)target.get_boxing_of(tc, ncrepr.ID);
if (call == null) {
call = new NativeCallBody();
target.set_boxing_of(tc, ncrepr.ID, call);
}
}
return call;
}
Expand Down
6 changes: 6 additions & 0 deletions src/vm/jvm/runtime/org/perl6/nqp/sixmodel/SixModelObject.java
Expand Up @@ -66,6 +66,12 @@ public void set_str(ThreadContext tc, String value) {
public String get_str(ThreadContext tc) {
throw ExceptionHandling.dieInternal(tc, "This representation can not unbox to a native str");
}
public void set_boxing_of(ThreadContext tc, long reprId, Object value) {
throw ExceptionHandling.dieInternal(tc, "This representation can not box another");
}
public Object get_boxing_of(ThreadContext tc, long reprId) {
throw ExceptionHandling.dieInternal(tc, "This representation can not unbox another");
}

/**
* Positional access functions.
Expand Down
21 changes: 20 additions & 1 deletion src/vm/jvm/runtime/org/perl6/nqp/sixmodel/reprs/NativeCall.java
Expand Up @@ -76,8 +76,27 @@ public void inlineDeserialize(ThreadContext tc, STable st, MethodVisitor mv, Str
/* Not supported. */
}

// XXX This is a hack as it fails to check the REPR ID, but the JVM will
// catch any screw-ups and keep us safe.
public void generateBoxingMethods(ThreadContext tc, STable st, ClassWriter cw, String className, String prefix) {
/* We don't box/unbox as any of the native types. */
String nativeCallType = Type.getType(NativeCallBody.class).getDescriptor();
String nativeCallIN = Type.getType(NativeCallBody.class).getInternalName();

String getDesc = "(Lorg/perl6/nqp/runtime/ThreadContext;J)Ljava/lang/Object;";
MethodVisitor getMeth = cw.visitMethod(Opcodes.ACC_PUBLIC, "get_boxing_of", getDesc, null, null);
getMeth.visitVarInsn(Opcodes.ALOAD, 0);
getMeth.visitFieldInsn(Opcodes.GETFIELD, className, prefix, nativeCallType);
getMeth.visitInsn(Opcodes.ARETURN);
getMeth.visitMaxs(0, 0);

String setDesc = "(Lorg/perl6/nqp/runtime/ThreadContext;JLjava/lang/Object;)V";
MethodVisitor setMeth = cw.visitMethod(Opcodes.ACC_PUBLIC, "set_boxing_of", setDesc, null, null);
setMeth.visitVarInsn(Opcodes.ALOAD, 0);
setMeth.visitVarInsn(Opcodes.ALOAD, 4);
setMeth.visitTypeInsn(Opcodes.CHECKCAST, nativeCallIN);
setMeth.visitFieldInsn(Opcodes.PUTFIELD, className, prefix, nativeCallType);
setMeth.visitInsn(Opcodes.RETURN);
setMeth.visitMaxs(0, 0);
}

// We don't depend on any details of the STable, so no description is needed
Expand Down

0 comments on commit 764b127

Please sign in to comment.