Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Flesh out container ops and code_pair cont.
This gets 67-container.t passing on the JVM.
  • Loading branch information
jnthn committed May 10, 2013
1 parent 866fe1a commit 2ec1cce
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 18 deletions.
2 changes: 2 additions & 0 deletions src/vm/jvm/runtime/org/perl6/nqp/runtime/GlobalContext.java
Expand Up @@ -2,6 +2,7 @@

import java.util.HashMap;

import org.perl6.nqp.sixmodel.CodePairContainerConfigurer;
import org.perl6.nqp.sixmodel.ContainerConfigurer;
import org.perl6.nqp.sixmodel.KnowHOWBootstrapper;
import org.perl6.nqp.sixmodel.SerializationContext;
Expand Down Expand Up @@ -155,6 +156,7 @@ public GlobalContext()
hllSyms = new HashMap<String, HashMap<String, SixModelObject>>();

contConfigs = new HashMap<String, ContainerConfigurer>();
contConfigs.put("code_pair", new CodePairContainerConfigurer());

mainThread = new ThreadContext(this);
KnowHOWBootstrapper.bootstrap(mainThread);
Expand Down
52 changes: 36 additions & 16 deletions src/vm/jvm/runtime/org/perl6/nqp/runtime/Ops.java
Expand Up @@ -34,6 +34,8 @@

import org.perl6.nqp.jast2bc.JASTToJVMBytecode;
import org.perl6.nqp.sixmodel.BoolificationSpec;
import org.perl6.nqp.sixmodel.ContainerConfigurer;
import org.perl6.nqp.sixmodel.ContainerSpec;
import org.perl6.nqp.sixmodel.InvocationSpec;
import org.perl6.nqp.sixmodel.REPRRegistry;
import org.perl6.nqp.sixmodel.STable;
Expand Down Expand Up @@ -1346,6 +1348,7 @@ public static long capturehasnameds(SixModelObject obj, ThreadContext tc) {
public static final CallSiteDescriptor emptyCallSite = new CallSiteDescriptor(new byte[0], null);
public static final Object[] emptyArgList = new Object[0];
public static final CallSiteDescriptor invocantCallSite = new CallSiteDescriptor(new byte[] { CallSiteDescriptor.ARG_OBJ }, null);
public static final CallSiteDescriptor storeCallSite = new CallSiteDescriptor(new byte[] { CallSiteDescriptor.ARG_OBJ, CallSiteDescriptor.ARG_OBJ }, null);
public static final CallSiteDescriptor findmethCallSite = new CallSiteDescriptor(new byte[] { CallSiteDescriptor.ARG_OBJ, CallSiteDescriptor.ARG_OBJ, CallSiteDescriptor.ARG_STR }, null);
public static void invoke(SixModelObject invokee, int callsiteIndex, Object[] args, ThreadContext tc) throws Exception {
// If it's lexotic, throw the exception right off.
Expand Down Expand Up @@ -1377,12 +1380,12 @@ public static void invoke(SixModelObject invokee, int callsiteIndex, Object[] ar

// TODO Find a smarter way to do this without all the pointer chasing.
if (callsiteIndex >= 0)
invokeInternal(tc, invokee, tc.curFrame.codeRef.staticInfo.compUnit.callSites[callsiteIndex], args);
invokeDirect(tc, invokee, tc.curFrame.codeRef.staticInfo.compUnit.callSites[callsiteIndex], args);
else
invokeInternal(tc, invokee, emptyCallSite, args);
invokeDirect(tc, invokee, emptyCallSite, args);
}
public static void invokeArgless(ThreadContext tc, SixModelObject invokee) {
invokeInternal(tc, invokee, emptyCallSite, new Object[0]);
invokeDirect(tc, invokee, emptyCallSite, new Object[0]);
}
public static void invokeMain(ThreadContext tc, SixModelObject invokee, String prog, String[] argv) {
/* Build argument list from argv. */
Expand All @@ -1397,9 +1400,9 @@ public static void invokeMain(ThreadContext tc, SixModelObject invokee, String p
}

/* Invoke with the descriptor and arg list. */
invokeInternal(tc, invokee, new CallSiteDescriptor(callsite, null), args);
invokeDirect(tc, invokee, new CallSiteDescriptor(callsite, null), args);
}
private static void invokeInternal(ThreadContext tc, SixModelObject invokee, CallSiteDescriptor csd, Object[] args) {
public static void invokeDirect(ThreadContext tc, SixModelObject invokee, CallSiteDescriptor csd, Object[] args) {
// Otherwise, get the code ref.
CodeRef cr;
if (invokee instanceof CodeRef) {
Expand Down Expand Up @@ -1429,7 +1432,7 @@ private static void invokeInternal(ThreadContext tc, SixModelObject invokee, Cal
public static SixModelObject invokewithcapture(SixModelObject invokee, SixModelObject capture, ThreadContext tc) throws Exception {
if (capture instanceof CallCaptureInstance) {
CallCaptureInstance cc = (CallCaptureInstance)capture;
invokeInternal(tc, invokee, cc.descriptor, cc.args);
invokeDirect(tc, invokee, cc.descriptor, cc.args);
return result_o(tc.curFrame);
}
else {
Expand Down Expand Up @@ -1548,7 +1551,7 @@ public static SixModelObject findmethod(SixModelObject invocant, String name, Th
/* Otherwise delegate to the HOW. */
SixModelObject how = invocant.st.HOW;
SixModelObject find_method = findmethod(how, "find_method", tc);
invokeInternal(tc, find_method, findmethCallSite,
invokeDirect(tc, find_method, findmethCallSite,
new Object[] { how, invocant, name });
return result_o(tc.curFrame);
}
Expand Down Expand Up @@ -1979,22 +1982,39 @@ public static long ishash(SixModelObject obj, ThreadContext tc) {

/* Container operations. */
public static SixModelObject setcontspec(SixModelObject obj, String confname, SixModelObject confarg, ThreadContext tc) {
/* XXX TODO */
if (obj.st.ContainerSpec != null)
ExceptionHandling.dieInternal(tc, "Cannot change a type's container specification");

ContainerConfigurer cc = tc.gc.contConfigs.get(confname);
if (cc == null)
ExceptionHandling.dieInternal(tc, "No such container spec " + confname);
cc.setContainerSpec(tc, obj.st);
cc.configureContainerSpec(tc, obj.st, confarg);

return obj;
}
public static long iscont(SixModelObject obj) {
return obj.st.ContainerSpec == null ? 0 : 1;
}
public static SixModelObject decont(SixModelObject obj, ThreadContext tc) {
if (obj.st.ContainerSpec == null)
return obj;
throw ExceptionHandling.dieInternal(tc, "Decontainerization NYI");
ContainerSpec cs = obj.st.ContainerSpec;
return cs == null ? obj : cs.fetch(tc, obj);
}
public static SixModelObject assign(SixModelObject cont, SixModelObject value, ThreadContext tc) {
throw ExceptionHandling.dieInternal(tc, "assign NYI");
ContainerSpec cs = cont.st.ContainerSpec;
if (cs != null)
cs.store(tc, cont, value);
else
ExceptionHandling.dieInternal(tc, "Cannot assign to an immutable value");
return cont;
}
public static SixModelObject assignunchecked(SixModelObject cont, SixModelObject value, ThreadContext tc) {
throw ExceptionHandling.dieInternal(tc, "assignunchecked NYI");
ContainerSpec cs = cont.st.ContainerSpec;
if (cs != null)
cs.storeUnchecked(tc, cont, value);
else
ExceptionHandling.dieInternal(tc, "Cannot assign to an immutable value");
return cont;
}

/* Iteration. */
Expand Down Expand Up @@ -2068,7 +2088,7 @@ public static long istrue(SixModelObject obj, ThreadContext tc) {
BoolificationSpec bs = obj.st.BoolificationSpec;
switch (bs == null ? BoolificationSpec.MODE_NOT_TYPE_OBJECT : bs.Mode) {
case BoolificationSpec.MODE_CALL_METHOD:
invokeInternal(tc, bs.Method, invocantCallSite, new Object[] { obj });
invokeDirect(tc, bs.Method, invocantCallSite, new Object[] { obj });
return istrue(result_o(tc.curFrame), tc);
case BoolificationSpec.MODE_UNBOX_INT:
return obj instanceof TypeObject || obj.get_int(tc) == 0 ? 0 : 1;
Expand Down Expand Up @@ -2113,7 +2133,7 @@ public static String smart_stringify(SixModelObject obj, ThreadContext tc) {
// bulk.
SixModelObject numMeth = obj.st.MethodCache.get("Str");
if (numMeth != null) {
invokeInternal(tc, numMeth, invocantCallSite, new Object[] { obj });
invokeDirect(tc, numMeth, invocantCallSite, new Object[] { obj });
return result_s(tc.curFrame);
}

Expand Down Expand Up @@ -2145,7 +2165,7 @@ public static double smart_numify(SixModelObject obj, ThreadContext tc) {
// bulk.
SixModelObject numMeth = obj.st.MethodCache.get("Num");
if (numMeth != null) {
invokeInternal(tc, numMeth, invocantCallSite, new Object[] { obj });
invokeDirect(tc, numMeth, invocantCallSite, new Object[] { obj });
return result_n(tc.curFrame);
}

Expand Down
@@ -0,0 +1,30 @@
package org.perl6.nqp.sixmodel;

import org.perl6.nqp.runtime.ExceptionHandling;
import org.perl6.nqp.runtime.ThreadContext;

/**
* A code_pair container uses a pair of methods (fetch/store) to provide the
* container semantics.
*/
public class CodePairContainerConfigurer extends ContainerConfigurer {
/* Sets this container spec in place for the specified STable. */
public void setContainerSpec(ThreadContext tc, STable st) {
st.ContainerSpec = new CodePairContainerSpec();
}

/* Configures the container spec with the specified info. */
public void configureContainerSpec(ThreadContext tc, STable st, SixModelObject config) {
CodePairContainerSpec cs = (CodePairContainerSpec)st.ContainerSpec;
SixModelObject fetch = config.at_key_boxed(tc, "fetch");
if (fetch == null)
throw ExceptionHandling.dieInternal(tc,
"Container spec 'code_pair' must be configured with a fetch");
SixModelObject store = config.at_key_boxed(tc, "store");
if (store == null)
throw ExceptionHandling.dieInternal(tc,
"Container spec 'code_pair' must be configured with a store");
cs.fetchCode = fetch;
cs.storeCode = store;
}
}
@@ -0,0 +1,48 @@
package org.perl6.nqp.sixmodel;

import org.perl6.nqp.runtime.Ops;
import org.perl6.nqp.runtime.ThreadContext;

/**
* A code_pair container uses a pair of methods (fetch/store) to provide the
* container semantics.
*/
public class CodePairContainerSpec extends ContainerSpec {
public SixModelObject fetchCode;
public SixModelObject storeCode;

/* Fetches a value out of a container. Used for decontainerization. */
public SixModelObject fetch(ThreadContext tc, SixModelObject cont) {
Ops.invokeDirect(tc, fetchCode, Ops.invocantCallSite, new Object[] { cont });
return Ops.result_o(tc.curFrame);
}

/* Stores a value in a container. Used for assignment. */
public void store(ThreadContext tc, SixModelObject cont, SixModelObject obj) {
Ops.invokeDirect(tc, storeCode, Ops.storeCallSite, new Object[] { cont, obj });
}

/* Stores a value in a container, without any checking of it (this
* assumes an optimizer or something else already did it). Used for
* assignment. */
public void storeUnchecked(ThreadContext tc, SixModelObject cont, SixModelObject obj) {
store(tc, cont, obj);
}

/* Name of this container specification. */
public String name() {
return "code_pair";
}

/* Serializes the container data, if any. */
public void serialize(ThreadContext tc, STable st, SerializationWriter writer) {
writer.writeRef(fetchCode);
writer.writeRef(storeCode);
}

/* Deserializes the container data, if any. */
public void deserialize(ThreadContext tc, STable st, SerializationReader reader) {
fetchCode = reader.readRef();
storeCode = reader.readRef();
}
}
Expand Up @@ -18,7 +18,7 @@ public abstract class ContainerSpec {
public abstract void storeUnchecked(ThreadContext tc, SixModelObject cont, SixModelObject obj);

/* Name of this container specification. */
public String name;
public abstract String name();

/* Serializes the container data, if any. */
public abstract void serialize(ThreadContext tc, STable st, SerializationWriter writer);
Expand Down
Expand Up @@ -533,7 +533,7 @@ private void serializeStable(STable st) {
/* Container spec. */
writeInt(st.ContainerSpec == null ? 0 : 1);
if (st.ContainerSpec != null) {
writeStr(st.ContainerSpec.name);
writeStr(st.ContainerSpec.name());
st.ContainerSpec.serialize(tc, st, this);
}

Expand Down

0 comments on commit 2ec1cce

Please sign in to comment.